New User?   Join Now     Login            Forgot Password?    
XamlQuery v1.2
How XamlQuery Works?
Posted on Aug-08-2010 (6709 hits)

The following sections explain the techniques used internally by XamlQuery in order to traverse through the runtime (rendered) control tree and accomplish the tasks.

Finding Parent Controls

The AllParents() method of XamlQuery finds all the parents (upto root control) in the rendered Silverlight page.

public static ControlSet AllParents(DependencyObject control)
{
    ControlSet allParents = new ControlSet();

    while (true)
    {
        DependencyObject parent = VisualTreeHelper.GetParent(control);
        if (parent == null) break;
        else
        {
            allParents.Add(parent);
            control = parent;
        }
    }

    return (allParents);
}

The FindRoot() method of XamlQuery is used to find the topmost parent (root) control of the Silverlight tree. The root control will be usually UserControl or Page. This function accepts any control as argument and finds the root control by traversing the whole XAML tree upwards. If a UserControl or Page is embedded within another UserControl or Page, the later will be returned as root.

public static DependencyObject Root(DependencyObject control)
{
    while (true)
    {
        DependencyObject parent = VisualTreeHelper.GetParent(control);
        if (parent == null) return (parent);
        control = parent;
    }
}

The ParentByName() method of XamlQuery is used to find a parent control using its name. This is very useful while using data-templates. Unlike in other traditional markup languages like HTML and ASP.NET, Silverlight allows to have more than one control under a same name (but in different control paths). This function traverses the XAML tree upwards, starting from the given control and returns the first control with a specified name.

public static DependencyObject ParentByName(DependencyObject control, string parentName)
{
    while (true)
    {
        DependencyObject parent = VisualTreeHelper.GetParent(control);
        if (parent is FrameworkElement && ((FrameworkElement)parent).Name.Equals(parentName)) return (parent);
        else if (parent == null) return (null);
        control = parent;
    }
}

Finding Child Controls by Name and Type

The following class ChildrenFinder is an internal class of XamlQuery, used to recursively find all child controls or to find all child controls by a given type. For example, you can find all text-boxes or labels inside a control and its data-templates / control-templates. The search is performed in all sub-trees of the specified-control. Also, the All and FindByType functions in this class are good examples of using recursion in tree traversal.

public class ChildrenFinder
{
    public List<DependencyObject> Children { get; set; }
	
    public ChildrenFinder()
    {
        this.Children = new List<DependencyObject>();
    }
	
    public void All(DependencyObject control)
    {
        int childrenCount = VisualTreeHelper.GetChildrenCount(control);
        for (int childIndex = 0; childIndex < childrenCount; childIndex++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(control, childIndex);
            this.Children.Add(child);
            All(child);
        }
    }

    public void FindByType<T>(DependencyObject control)
    {
        int childrenCount = VisualTreeHelper.GetChildrenCount(control);
        for (int childIndex = 0; childIndex < childrenCount; childIndex++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(control, childIndex);
            if (child is T)
            {
                this.Children.Add(child);
            }
            FindByType<T>(child);
        }
    }
}

About      Terms      Contact