Sunday 24 July 2011

SQL Server Enable xp_cmdshell Option

Introduced in SQL Server 2005, the xp_cmdshell option is a server configuration option that enables system administrators to control whether the xp_cmdshell extended stored procedure can be executed on a system. By default, the xp_cmdshell option is disabled on new installations and can be enabled by using the Policy-Based Management or by running the sp_configure system stored procedure as shown in the following code example:


-- To allow advanced options to be changed.
EXEC sp_configure 'show advanced options', 1
GO
-- To update the currently configured value for advanced options.
RECONFIGURE
GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 1
GO
-- To update the currently configured value for this feature.
RECONFIGURE
GO

Friday 22 July 2011

SplineSeries for the Silverlight Toolkit - C# Code

While the Silverlight Toolkit has made some amazing strides in improving, it still lacks some functionality compared to other toolkit offerings. In particular, Silverlight Toolkit's charts lack splines, or smoothed lines. The idea here is that we don't want the graph to appears as though a line is moving from point to point directly -- that it moves parabolically, or softer.




A typical line series.



Now, this is all fun and games, but can we get something where transitions are more smooth? Yes, we can.




A spline series.



Notice, the spline series changes are more gradual and curved. Are they an entirely accurate representation of the in-between? No, not always -- but they're not meant to be (necessarily).



The Spline Series is literally a copy/paste of the LineSeries, with a few changes. Note that this is located under the Charting/Series folder of the DataVisualization.Toolkit project. Essentially, what we want to do is change the Polyline to a Path. The idea here is that a Polyline doesn't draw Beziers. Below is my (large) code,



SplineSeries.cs:



// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
 
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Windows.Media;
using System.Windows.Shapes;
 
#if !DEFINITION_SERIES_COMPATIBILITY_MODE
 
namespace System.Windows.Controls.DataVisualization.Charting
{
    /// <summary>
    /// Represents a control that contains a data series to be rendered in X/Y 
    /// line format.
    /// </summary>
    /// <QualityBand>Preview</QualityBand>
    [StyleTypedProperty(Property = DataPointStyleName, StyleTargetType = typeof(LineDataPoint))]
    [StyleTypedProperty(Property = "LegendItemStyle", StyleTargetType = typeof(LegendItem))]
    [StyleTypedProperty(Property = "PathStyle", StyleTargetType = typeof(Path))]
    [TemplatePart(Name = DataPointSeries.PlotAreaName, Type = typeof(Canvas))]
    [SuppressMessage("Microsoft.Maintainability", "CA1501:AvoidExcessiveInheritance", Justification = "Depth of hierarchy is necessary to avoid code duplication.")]
    public partial class SplineSeries : LineAreaBaseSeries<LineDataPoint>
    {
        #region public PointCollection Points
        /// <summary>
        /// Gets the collection of points that make up the spline.
        /// </summary>
        public PointCollection Points
        {
            get { return GetValue(PointsProperty) as PointCollection; }
            private set { SetValue(PointsProperty, value); }
        }
 
        /// <summary>
        /// Identifies the Points dependency property.
        /// </summary>
        public static readonly DependencyProperty PointsProperty =
            DependencyProperty.Register(
                "Points",
                typeof(PointCollection),
                typeof(SplineSeries),
                null);
        #endregion public PointCollection Points
 
        #region public PathGeometry SplinePoints
        /// <summary>
        /// Gets the collection of points that make up the line.
        /// </summary>
        public PathGeometry SplinePoints
        {
            get { return GetValue(SplinePointsProperty) as PathGeometry; }
            private set { SetValue(SplinePointsProperty, value); }
        }
 
        /// <summary>
        /// Identifies the SplinePoints dependency property.
        /// </summary>
        public static readonly DependencyProperty SplinePointsProperty =
            DependencyProperty.Register(
                "SplinePoints",
                typeof(PathGeometry),
                typeof(SplineSeries),
                null);
        #endregion public PathGeometry SplinePoints
 
        #region public double SplineTension
 
        /// <summary>
        /// Gets or sets the tension in the beziers that make up the spline.
        /// </summary>
        /// <remarks>
        /// The greater the tension, the more straight/linear the spline will look.
        /// Less tension creates a more curvy spline.
        /// </remarks>
        public double SplineTension
        {
            get { return (double) GetValue(SplineTensionProperty); }
            set { SetValue(SplineTensionProperty, value); }
        }
 
        /// <summary>
        /// Identifies the SplineTension dependency property.
        /// </summary>
        public static readonly DependencyProperty SplineTensionProperty =
            DependencyProperty.Register(
                "SplineTension",
                typeof(double),
                typeof(SplineSeries),
                new PropertyMetadata(2.5));
        #endregion public double SplineTension
 
        #region public Style PathStyle
        /// <summary>
        /// Gets or sets the style of the Path object that follows the data 
        /// points.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Path", Justification = "Matches System.Windows.Shapes.Path.")]
        public Style PathStyle
        {
            get { return GetValue(PathStyleProperty) as Style; }
            set { SetValue(PathStyleProperty, value); }
        }
 
        /// <summary>
        /// Identifies the PathStyle dependency property.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Path", Justification = "Matches System.Windows.Shapes.Path.")]
        public static readonly DependencyProperty PathStyleProperty =
            DependencyProperty.Register(
                "PathStyle",
                typeof(Style),
                typeof(SplineSeries),
                null);
        #endregion public Style PathStyle
 
#if !SILVERLIGHT
        /// <summary>
        /// Initializes the static members of the LineSeries class.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "Dependency properties are initialized in-line.")]
        static SplineSeries()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(SplineSeries), new FrameworkPropertyMetadata(typeof(SplineSeries)));
        }
 
#endif
        /// <summary>
        /// Initializes a new instance of the LineSeries class.
        /// </summary>
        public SplineSeries()
        {
#if SILVERLIGHT
            this.DefaultStyleKey = typeof(SplineSeries);
#endif
        }
 
        /// <summary>
        /// Acquire a horizontal linear axis and a vertical linear axis.
        /// </summary>
        /// <param name="firstDataPoint">The first data point.</param>
        protected override void GetAxes(DataPoint firstDataPoint)
        {
            GetAxes(
                firstDataPoint,
                (axis) => axis.Orientation == AxisOrientation.X,
                () =>
                {
                    IAxis axis = CreateRangeAxisFromData(firstDataPoint.IndependentValue);
                    if (axis == null)
                    {
                        axis = new CategoryAxis();
                    }
                    axis.Orientation = AxisOrientation.X;
                    return axis;
                },
                (axis) => axis.Orientation == AxisOrientation.Y && axis is IRangeAxis,
                () =>
                {
                    DisplayAxis axis = (DisplayAxis)CreateRangeAxisFromData(firstDataPoint.DependentValue);
                    if (axis == null)
                    {
                        throw new InvalidOperationException(Properties.Resources.DataPointSeriesWithAxes_NoSuitableAxisAvailableForPlottingDependentValue);
                    }
                    axis.ShowGridLines = true;
                    axis.Orientation = AxisOrientation.Y;
                    return axis;
                });
        }
 
        /// <summary>
        /// Updates the Series shape object from a collection of Points.
        /// </summary>
        /// <param name="points">Collection of Points.</param>
        protected override void UpdateShapeFromPoints(IEnumerable<Point> points)
        {
            if (points.Any())
            {
                PointCollection pointCollection = new PointCollection();
                foreach (Point point in points)
                {
                    pointCollection.Add(point);
                }
 
                //At least two points are necessary to generate a proper spline
                if (pointCollection.Count >= 2)
                {
                    PathGeometry geometry = new PathGeometry();
                    PathFigure figure = new PathFigure();
 
                    PointCollection bezierPoints = GetBezierPoints(pointCollection);
 
                    figure.StartPoint = bezierPoints[0];
                    for (int i = 1; i < bezierPoints.Count; i += 3)
                    {
                        figure.Segments.Add(new BezierSegment()
                            {
                                Point1 = bezierPoints[i],
                                Point2 = bezierPoints[i + 1],
                                Point3 = bezierPoints[i + 2]
                            });
                    }
 
                    geometry.Figures.Add(figure);
                    SplinePoints = geometry;
                }
                else
                {
                    SplinePoints = null;
                }
 
                Points = pointCollection;
            }
            else
            {
                Points = null;
                SplinePoints = null;
            }
        }
 
        #region Bezier Curve Building
 
        /*
         * Formulas and code pulled from Kerem Kat's MapBezier example:
         * http://www.codeproject.com/KB/silverlight/MapBezier.aspx
         */ 
 
        private PointCollection GetBezierPoints(PointCollection pts)
        {
            PointCollection ret = new PointCollection();
 
            for (int i = 0; i < pts.Count; i++)
            {
                // for first point append as is.
                if (i == 0)
                {
                    ret.Add(pts[0]);
                    continue;
                }
 
                // for each point except first and last get B1, B2. next point. 
                // Last point do not have a next point.
                ret.Add(GetB1(pts, i - 1, SplineTension));
                ret.Add(GetB2(pts, i - 1, SplineTension));
                ret.Add(pts[i]);
            }
 
            return ret;
        }
 
        private Point GetB1(PointCollection pts, int i, double a)
        {
            Point  derivedPoint = GetDerivative(pts, i, a);
            return new Point(pts[i].X + derivedPoint.X / 3, pts[i].Y + derivedPoint.Y / 3);
        }
 
        private Point GetB2(PointCollection pts, int i, double a)
        {
            Point derivedPoint = GetDerivative(pts, i+1, a);
            return new Point(pts[i + 1].X - derivedPoint.X / 3, pts[i + 1].Y - derivedPoint.Y / 3);
        }
 
        private Point GetDerivative(PointCollection pts, int i, double a)
        {
            if (pts.Count < 2)
                throw new ArgumentOutOfRangeException("pts", "Data must contain at least two points.");
  
            if (i == 0)
            {
                // First point.
                return new Point((pts[1].X - pts[0].X) / a, (pts[1].Y - pts[0].Y) / a);
            }
            if (i == pts.Count - 1)
            {
                // Last point.
                return new Point((pts[i].X - pts[i - 1].X) / a, (pts[i].Y - pts[i - 1].Y) / a);
            }
  
            return new Point((pts[i + 1].X - pts[i - 1].X) / a, (pts[i + 1].Y - pts[i - 1].Y) / a);
        }
        #endregion
    }
}
 
#endif



Note that I borrowed my Spline/Bezier code from Kerem Kat's example: http://www.codeproject.com/KB/silverlight/MapBezier.aspx

Essentially what it does, is takes prior points to adjust such that they curve into the next. The UpdateShapeFromPoints method was changed from the standard LineSeries and uses all of the helper methods that were added to calculate a Bezier curve.

We're pretty much almost done, except for one more minor touch. We need to have the default style included, such that it complies with how Silverlight Toolkit handles it's control templating. We add the following chunk of code to Themes\generic.xaml of the same project:


    <!--  charting:SplineSeries  -->
    <Style TargetType="charting:SplineSeries">
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="PathStyle">
            <Setter.Value>
                <Style TargetType="Path">
                    <Setter Property="StrokeThickness" Value="2" />
                    <Setter Property="StrokeMiterLimit" Value="1" />
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="charting:SplineSeries">
                    <Canvas x:Name="PlotArea">
                        <Path Data="{TemplateBinding SplinePoints}" Stroke="{TemplateBinding Background}" Style="{TemplateBinding PathStyle}"/>
                        <Polyline Points="{TemplateBinding Points}" />
                    </Canvas>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Now, just recompile the Toolkit and you should be good to go!

I've included a "patch" with these files and their updates -- they should be capable of being pasted over their old versions (the Themes\generic.xaml just has the SplineSeries.xaml pasted into it -- I would strongly recommend you doing this with your own source):

https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0B9hGvs6yJgfJNzA4YmE1OTctNzNmYy00MzMzLWJhNDQtNTc0M2FlNTA3NzFm&hl=en_US

Tuesday 12 July 2011

SilverlightToolkit Development/Building Guidance

If you're like me and want to alter some of Silverlight Toolkit's behavior (or add more functionality to it), chances are your builds will not work perfectly and you'll be in a constant state of mismatched assemblies.

I've noticed that Silverlight Toolkit has some major issues with the entire build process -- only loading different components and making references to other DLL's (which get deleted if you perform a clean build), not other projects. The second those are removed from the Binaries directory, the entire system goes to hell and back, eventually grabbing references to your DLL's in the Silverlight Toolkit install directory (somewhere in your root drive under Program Files, etc). What a pain! Then you'd have to go back and rebuild the references and re-specify their location. There has to be a better way, right?

Kind of.

What I ended up doing, and I highly recommend this for anyone working with Silverlight Toolkit on a regular basis -- is to build a new solution, rather than use the existing ones. Don't worry about including their Design or Testing projects, unless they're important to you. Then follow this process:

1. Build a new solution and include all relevant projects.

As stated before, place everything that you actually care about building. In my case, I was only concerned about the actual controls - not the testing or design. Since I'm already heavily involved with using the controls, I'll know if they're broken in test or design scenarios.
2. (Optional) Rename all projects to their full assembly name, rather than a shorthand version.

When viewing their projects, you'll notice things like Controls.Data or System.Controls, which are all very misleading. Everything falls under System.Windows.*. For sake of clarity, I found myself renaming them, so when I would eventually add references back to other projects, I could see the full name of the project/assembly built.
3. Change build path in each project, for all build-types, to a single directory.

You'd be surprised how many different places the assemblies for Silverlight Toolkit get built to. Each project seems to be written by someone else, with their own styles/paths for where assemblies that are built get stored. I simplified everything and made everything build to the Binaries folder -- always.
4. Referenced assemblies from other SDKs should be placed in a special folder under the build path.

This is a pattern we have at work -- if you build something that requires a reference to an SDK other than our own, you drop the assembly in a References project and store everything in source control for the entire team to use. You won't have to install the toolkits for other team members at this point, since they'll be in a standard location. For Design and Testing projects, SilverlightToolkit uses other SDKs, so this is vital for those of you wishing to build these.
5. Remove all references to SilverlightToolkit projects and re-add them as a reference to the projects in your solution.

As stated before, the references all get built to different places, which can cause for some crazy issues when you perform a clean. They then default back to your SilverlightToolkit install. It's horribly complicated. Referencing your projects will create appropriate dependencies that cause everything to build correctly and together. You can imagine what will happen to System.Windows.Controls.DataVisualizations when it tries to reference System.Windows.Controls and the assemblies are built at different times with different dependencies. If you can't, imagine shear sacrilege. And pain. And suffering.
If you follow these guidelines, you should have a much more stable/clean build of SilverlightToolkit, which will make future developments and enhancements easier to bake in (such as targeting a WPF platform for Charting). Unfortunately SilverlightToolkit also no longer accepts user contributions, due to licensing issues, and Microsoft is the sole development team. This makes getting features added a little (read: very) difficult.

Good luck and happy building!

Thursday 7 July 2011

Embedding (Silverlight) Content in SharePoint Webparts

I'm going to start this off by saying that I am, by no means, a SharePoint expert. Developing for SharePoint is painful, but also rewarding. When it works, you feel an immense amount of pride that your solution worked after all of your labor. However, there's the immeasurable pain and headaches that come from attempting to write it.

That being said, I did find a very clever way of embedding a piece of content (in my case, a Silverlight xap -- but this could be anything, a JPEG, PNG, MP3, etc) into a SharePoint webpart. Given my background of making everything work on multiple platforms, I wanted to have the simplest possible way of doing this, without having to continually go back and forth with new code. Given I'm also trying to write a platform of tools and controls, this enables me to make a standardized package where we're not going to have conflicts with different versions of a chunk of content in the layouts folder with different assemblies/features installed.

The jist of this is that we're going to have ASP.NET share the content through a compiled DLL. Seems complicated? Not as much as you'd think. It's a relatively simple process:

  1. Add content to your project.
  2. Add information about the resource to your assembly.
  3. Utilize the resource.
First things first -- make sure you have a SharePoint project setup in Visual Studio 2010. I imagine this will probably work in prior versions of Visual Studio, but I haven't tested it.

1. Add content to your project.

Originally, I wanted to do things the "right" way for embedding my content -- I wanted to add each file into the mapped Layouts folder that Visual Studio 2010 gracefully provides. However, a minor issue arose from this -- my content is changing dynamically, and I needed to add it as a linked item (like the way I've done with Silverlight and WPF controls). Since the file is linked and not actually in the folder, Visual Studio doesn't have it in the directory and thus, it is not built. You could potentially make a script to copy it back/forth after the content is built (in my case, it's a Silverlight xap), but then you have issues with checking it out, etc.

Instead, we want to link it, since that's much, much, much easier. It prevents a lot of issues that could also result with conflicting and different features, in the event of any major issues with deployment.

So, I created a folder in my project called "Resources" where I would link this in. In this example, I have a Silverlight application called "HelloWorld.xap" and will be linking in the existing xap from the Release directory. Make sure that this is included as an "Embedded Resource" from the "Build Actions."



Gotta love our Hello World applications!


Now, that we have that done, we can get to the slightly uglier part.

2. Add information about the resource to your assembly.

In the SharePoint project, we need to open up AssemblyInfo.cs under Properties and edit it very minorly. We want to add in the new resource we have. I had to add in a reference to System.Web, and you likely will too.

At the bottom of the file, you will need to add one entry per resource, as follows:


[assembly: System.Web.UI.WebResource("EmbeddedSPContent.Resources.HelloWorld.xap", "application/x-silverlight-2")]

The first parameter of System.Web.UI.WebResource is the name of the file and its location in the project. Notice that to notate paths/directories, we need to use periods instead of slashes.

The second parameter of System.Web.UI.WebResource is the mime-type. What do you want the DLL to tell the browser that the file is? In my case, I want it to be recognized as a Silverlight application. This could potentially be a PNG, MP3, and so forth.

Still hanging on there? Cool, because we're almost done.



3. Utilize the resource.



Ah, yes -- the most important part. We have to actually use it now. But that's simple. I'm going to build a pretty standard WebPart and override RenderContents.


I added the following code to render it (a very quick/dirty Silverlight HTML mockup):


string resourceUrl = Page.ClientScript.GetWebResourceUrl(GetType(), "EmbeddedSPContent.Resources.HelloWorld.xap");
 
            string control = @"
            <div id=""silverlightControlHost"">
                <object data=""data:application/x-silverlight-2,"" type=""application/x-silverlight-2"" width=""400px"" height=""400px"">
                    <param name=""source"" value=""{MY_URL}"" />
                    <param name=""minRuntimeVersion"" value=""4.0.50826"" />
 
                    <a href=""http://go.microsoft.com/fwlink/?LinkID=149156&amp;v=4.0.50826.0"" style=""text-decoration:none"">
                        <img src=""http://go.microsoft.com/fwlink/?LinkId=108181"" alt=""Get Microsoft Silverlight"" style=""border-style:none"" />
                    </a>
                </object>
            </div>";
 
            control = control.Replace("{MY_URL}", resourceUrl);
 
            writer.Write(control);


and look at the below, it works!



I know what you're thinking -- that's a sexy web part.

The sample is included on MSDN for others to use, so this will hopefully make it easier to follow what was done:

http://code.msdn.microsoft.com/Embedding-Resources-for-d61b251d

Please note that in order to get this working, we have to deploy it as a Farm Solution, rather than a Sandboxed Solution.

Saturday 2 July 2011

Difference Between Firefox 4 and Firefox 5

Firefox is the second most widely used web browser in the world. It is used by thirty-percent of browser users worldwide. Firefox 4 was released on March 22, 2011 with major improvement over Firefox 3.6. But few weeks later Mozilla announced the release of Firefox 5 due to their new rapid release cycle (much like Google’s), and it was released in June, 2011. Although, Firefox 4 included major changes compared to its previous version, most expert reviewers agree that Firefox 5 and Firefox 4 are very similar and the changes seen on Firefox 5 do not merit a full version number.

Firefox 4

Firefox 4 was a major improvement over its earlier edition. Firefox 4 adds improved support for HTML5, CSS3, WebM and WebGL, by utilizing the power of Gecko 2.0 engine. A new JavaScript engine called JägerMonkey is included. The primary goals for the version 4 of this already impressive browser were improvements in performance, standards support, and user interface. Firefox 4 introduced a new and improved user interface to make it faster. A feature called Firefox Panorama allows the user to organize tabs into windows called groups and apply same operation on all tabs in a group. By default, tabs are now on top of the page, almost exactly similar to Chrome. Stop, Reload and Go buttons have been combined in to a single button, which changes state according to the current state of the page.

An audio API has been introduced in Firefox 4, which allows programmatically accessing or creating audio data associated with HTML5 audio element. This feature can be used to visualize, filter or show audio spectrums. Firefox 4 now offers a consistent layout/shaping across different operating systems. Other notable features are doorhanger notifications, application tabs and support for multitouch displays.

Firefox 5

Firefox 5 was released in June 21, 2011. Because Firefox 5 was released in a very short time (just after 3 months) after Firefox 4’s release date, there are no major changes to the GUI. But there are plenty of minor additions, improvements and bug fixes, that are claimed to help Firefox 5 relatively more secure, stable and usable. Along with all the new features introduced in Firefox 4, there is a new “Do Not Track” button in the preference menu in Firefox 5, which makes it very convenient to opt-out from advertisement companies that track the web history to display customized ads. In fact, Firefox 5 for Android is the first mobile browser with this feature. Firefox 5 includes a channel switcher to switch between the beta version and other test versions. Firefox 5 adds support for CSS animations. It includes better Linux support as well. Furthermore, they say Firefox 5 has better support for HTML5, XHR, SMIL, CSS3 and Math ML.

What’s the difference between Firefox 4 and Firefox 5

Although, Firefox 4 introduced lots of impressive features over its earlier release, Firefox 5 only adds minor improvements and few new features. Visually, Firefox 5 looks almost the same as Firefox 4. But, Firefox 5 is said to be more secure and more stable than Firefox 4. Two such notable features are the “Do Not Track” button and channel switcher in Firefox 5. Firefox 5 actually makes the “Do Not Track” header preference more visible and easily reachable. It is estimated that Firefox 5 provides improved memory, JavaScript, canvas and networking performance compared to Firefox 4. Firefox 5’s HTTP idle connection logic is better tuned compared to Firefox 4. Firefox 5 includes improved spell checking for more locales than Firefox 4. Mozilla claims that Firefox 5 provides dramatic performance improvement for its Linux users. Furthermore, Firefox 5 offers better support for web standards such as HTML5 and CSS3.

Mozilla claim that there are over thousand improvements in Firefox 5 (but most of them are bug fixes related to crashes, fonts, etc.). Therefore, Firefox 5 is claimed to be more stable than its predecessor. Firefox developers have improved the WebGL security by not allowing Firefox 5 to load cross-domain textures. To improve the performance of tabs, Firefox 5’s both setInterval and setTimeout have been set to 100 Milliseconds. According to several software critics that reviewed Firefox 5 after its release, although changes in other areas in Firefox 5 are minor, in terms of improvements in the areas of security, stability and usability, Firefox 5 is well worth the upgrade.



VisualTreeHelper

Ever noticed that WPF and Silverlight don't like to play nicely with their implementations of the same controls? Often, this is because they are derived differently. They both ultimately derive from DependencyObject, however the

In any case, the VisualTreeHelper is your best friend when it comes to navigating the structure of your controls. Essentially, it allows you to navigate down from a parent element, locating children. You can be a little recursive and then use the VisualTreeHelper on the child controls and dig deeper and deeper.

I've written a little helper that I've injected into the base class of all controls I'm writing for Silverlight and WPF.

/// <summary>
/// Navigates the control tree to find a child of a specific type.
/// </summary>
/// <param name="element">The parent element to search under.</param>
/// <param name="type">The type to search for.</param>
/// <returns>The first child of the specified type on success or null on failure.</returns>
protected object GetChildOfType(FrameworkElement element, Type type)
{
    int count = VisualTreeHelper.GetChildrenCount(element);
 
    for (int i = 0; i < count; i++)
    {
        FrameworkElement child = (FrameworkElement)VisualTreeHelper.GetChild(element, i);
 
        if (child != null)
        {
            if (child.GetType() == type)
                return child;
 
            object deeperChild = GetChildOfType(child, type);
 
            if (deeperChild != null)
                return deeperChild;
        }
    }
 
    return null;
}


Enjoy!