wpfxamldata-bindingdatagridtemplatebinding

What does a WPF DataGrid bind to the headers DataTemplate?


When creating a WPF DataGrid, I have the option to set a DataTemplate to each column's HeaderTemplate, like this:

<DataGridTextColumn Binding="{Binding Name}">
    <DataGridTextColumn.HeaderTemplate>
        <DataTemplate>

            <!-- just some random content, not important, but notice the bindings use RelativeSource-->
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Name" VerticalAlignment="Center"/>
                <Button Command="{Binding Path=DataContext.SortFoldersByNameCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" Content="▲" 
                    Foreground="{Binding Path=DataContext.IsFoldersSortByName, Converter={StaticResource EnabledToBrushConverter}, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
            </StackPanel>


        </DataTemplate>
    </DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>

Now, notice that for my bindings to work inside that template, I need to set a RelativeSource, because this template is not bound to the grid's DataContext anymore.

The question is: what is bound to the header's DataTemplate?

If I simply try to put a <TextBlock Text="{Binding}"/>, for instance, the text is empty. I don't know what other kinds of tests I could do to find out.


Solution

  • The short answer is that the datacontext is nothing.

    I threw a quick template into some datagrid I have on disk.

    I used this thing to answer a few questions years back.

    The header isn't in the visual tree and does not inherit datacontext.

    My quick and dirty header template:

                <DataGridTextColumn Binding="{Binding LastName}">
                    <DataGridTextColumn.HeaderTemplate>
                        <DataTemplate>
                            <TextBlock Text="XXXX"/>
                        </DataTemplate>
                    </DataGridTextColumn.HeaderTemplate>
                </DataGridTextColumn>
    

    Examine that textblock using Snoop...

    Datacontext is empty:

    enter image description here

    This is why you do all that relativesource stuff to get to your property in the datacontext.

    As an aside.

    If you're doing much wpf development I recommend you give Snoop a go.

    It's still way better than the in built thing.