Jacob Pitts
Jacob Pitts

Reputation: 47

On a WPF DataGrid bound to a DataTable, how can I generically change the Column Header template?

From an interface with another part of my project, I have a DataTable object which contains a variable number of columns and rows. I am trying to design a DataGrid that will show the table via binding, but customize the column headers for each column with some options (ex a TextBox under the header).

This is very similar to a previously asked question WPF Custom datagrid column header, except that I don't want to define the columns in WPF; but rather a template for columns which propagates across each column during binding.

The previous answer gets the right look, but when a DataGrid with that WPF style is bound to a DataTable, the result is a static single column with the additional red boardered TextBox, plus a bunch of bound columns which do not contain the textbox:

<DataGrid>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Name}"
                            Header="{Binding HeaderName}">
            <DataGridTextColumn.HeaderTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Content, RelativeSource=
                                     {RelativeSource Mode=TemplatedParent}}"
                                   Margin="5"/>
                        <TextBox BorderBrush="Red" BorderThickness="3"
                                 Width="50" Margin="5"/>
                    </StackPanel>
                </DataTemplate>
            </DataGridTextColumn.HeaderTemplate>
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

Instead of having the WPF above create a first column, how do I change it to have that specify the template of how bound columns should be rendered?

Thanks!

Upvotes: 0

Views: 1577

Answers (1)

Funk
Funk

Reputation: 11221

You can do it in Style

<DataGrid.Resources>
    <Style TargetType="{x:Type DataGridColumnHeader}">
        <Style.Triggers>
            <Trigger Property="HasContent" Value="True">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <StackPanel>
                                <TextBlock Text="{Binding Content, RelativeSource=
                                           {RelativeSource Mode=TemplatedParent}}"/>
                                <TextBox BorderBrush="Red" BorderThickness="3"
                                         Width="50" Margin="5"/>
                            </StackPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</DataGrid.Resources>

There seems to be a "MainHeader" for the entire DataGrid also, note the HasContent Trigger to eliminate this header from the Style.

Upvotes: 2

Related Questions