Accessing Controls from DataGrid ColumnHeader - Silverlight

Access the controls defined in Data Template from the code behind .


If you have ever worked with a DataGrid and columnHeader template then you might have faced a scenario where you need to access the controls defined in a style.  In this post we will discuss how to retrieve the same at runtime from the code behind.

1.png

The Issue

As shown above, the first column of the grid is assigned with a ColumnHeader style which holds 2 controls.

2.png

Now the highlighted controls need to be retrieved from the code behind.

The Solution

The VisualTreeHelper class helps to iterate through the visual tree of the xaml.Using it we can find the child and parent controls of the rendered controls.Lets check the Visual Tree of the rendered control using Silverlight Spy , if you missed my post on this must have tool then feel free  to have a look here.

3.png

The Following Method do a search over the child controls with in a control recursively and returns the control based on Name

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private object GetChildControl(DependencyObject parent, string controlName)
{
 
    Object tempObj = null;
    int count = VisualTreeHelper.GetChildrenCount(parent);
    for (int counter = 0; counter < count; counter++)
    {
        //Get The Child Control based on Index
        tempObj = VisualTreeHelper.GetChild(parent, counter);
 
        //If Control's name Property matches with the argument control
        //name supplied then Return Control
        if ((tempObj as DependencyObject).GetValue(NameProperty).ToString() == controlName)
            return tempObj;
        else //Else Search Recursively
        {
            tempObj = GetChildControl(tempObj as DependencyObject, controlName);
            if (tempObj != null)
                return tempObj;
        }
    }
    return null;
}

While implementing the method make sure that the same has to be delegated to UI thread using Dispatcher.As the controls created using UI Thread can not be accessed from other thread.

1
2
3
4
5
6
//Access the Grid Header Controls
Dispatcher.BeginInvoke(delegate
{
    var hyperlinkControl = GetChildControl(dataGrid1, "hlSort");
    var checkControl = GetChildControl(dataGrid1, "chkSelectAll");
});

Hope this will help Smile.