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

image

The Issue

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

image

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

The Solution

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.

image

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

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.

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

Hope this will help Smile.

Download the Source Code – : ColumnHeaderTemplete.zip