Accessing DataTemplate Elements in DataGrid HeaderTemplate

Dec 8, 2008 at 5:13 PM
I have created a custom header for my datagrid with textboxes and other controls, to allow a user to be able to filter on a particular column. Because I am creating a multi filter in code behind, I need to gain access not only to the controls value that is being updated, but also any other of the column header controls that may still contain content to be filtered on.  Here is some of my markup...



















<TextBlock Text="PACS"/>




<TextBox x:Name="PACSTextBox" TextChanged="FilterChanged"/>
























<TextBlock Text="{Binding PACS}" />














Right now in code behind I am handling the textbox changed events by assigning the values to a class member in code behind like so...



string PACSValue = null;



string InstitutionValue = null;





CollectionViewSource view = null;



private void FilterChanged(object sender, TextChangedEventArgs e)




TextBox t;



if (this.pacsItems == null)






if(view == null)


view =

new CollectionViewSource();


view.Source =




switch (((Control)sender).Name)




case "PACSTextBox":


PACSValue = ((



view.Filter -= PACSFilter;

view.Filter += PACSFilter;





case "InstitutionTextBox":




As you can see, what I did was create a class member in code behind for each of my filter controls and set the value when the text changed event is raised. Although this approach works fine, I would think accessing the controls values directly within my filters would be better than having to create global class members as I did. Is there a simple way to gain access to the controls in the header template?



Dec 9, 2008 at 2:44 AM
Does Template.FindName work for you. Following are the links with more details...,.

Dec 9, 2008 at 5:36 PM

I tryed both approaches and cannot get either to work.
The problem is that The findName takes a templatedParent as 1 of its argument and it does not accept a datagrid column like so




obj = dataGrid1.Columns[0].HeaderTemplate.FindName("DateInsertedTextBox",dataGrid1.Columns[0];

if I supply the dataGrid1 as the templated parent, I get a null result.

I am able to get a DataTemplate object when i use dataGrid1.Columns[0].HeaderTemplate, but that is as far as I can get. Any other suggestions?



Dec 9, 2008 at 7:29 PM
Column.HeaderTemplate.FindName wouldnt work because it is just a template definition but not the instance of a control. Instead you need to get the actual instance of the header call FindName on it. Following are the helper methods to get the header....

        private DataGridColumnHeadersPresenter GetColumnHeadersPresenter(DataGrid dataGrid)
            DataGridColumnHeadersPresenter chp = null;
            Control sv = dataGrid.Template.FindName("DG_ScrollViewer", dataGrid) as Control;
            if (sv != null)
                chp = sv.Template.FindName("PART_ColumnHeadersPresenter", sv) as DataGridColumnHeadersPresenter;
            return chp;

        private DataGridColumnHeader GetColumnHeader(int index, DataGrid dataGrid)
            DataGridColumnHeadersPresenter presenter = GetColumnHeadersPresenter(dataGrid);

            if (presenter != null)
                return (DataGridColumnHeader)presenter.ItemContainerGenerator.ContainerFromIndex(index);
            return null;

Then all you have to do is,
    DataGridColumnHeader header = GetColumnHeader(0, dataGrid);
    if(header != null)
        TextBox tb = header.Template.FindName("DataInsertedTextBox", header) as TextBox;

Dec 29, 2008 at 7:23 PM

Sorry for the late reply. I tried your suggestion but, this line of code is returning null:

chp = sv.Template.FindName("PART_ColumnHeadersPresenter", sv) as DataGridColumnHeadersPresenter;

The sv control is retreived with no problem. Any ideas why?
Dec 29, 2008 at 11:31 PM
Correction, I am able to get a DataGrdiColumnHeader but this line returns null:

TextBox tb = header.Template.FindName("DataInsertedTextBox", header) as TextBox;