Multilevel column header for DataGrid in WPF
As far as I know, the standard DataGrid
does not support it, so you need to look for alternatives. I can offer the use of a Grid
capabilities, such as: Grid.RowDefinitions
, Grid.ColumnDefinitions
. To illustrate this feature, I created a sample, who need to complete:
<Window x:Class="MultiHeaderDataGrid.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" WindowStartupLocation="CenterScreen"><Window.Resources> <Style TargetType="{x:Type Border}"> <Setter Property="Background" Value="Bisque" /> <Setter Property="TextBlock.FontSize" Value="14" /> <Setter Property="BorderBrush" Value="Black" /> <Setter Property="BorderThickness" Value="1" /> <Setter Property="HorizontalAlignment" Value="Stretch" /> </Style></Window.Resources><Grid> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="2*"/> </Grid.RowDefinitions> <Grid Grid.Row="0"> <Border Grid.Column="1" Grid.ColumnSpan="4"> <TextBlock Text="Main application" TextAlignment="Center" /> </Border> </Grid> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Border Grid.Column="0"> <TextBlock Grid.Column="1" Text="Experiment 1" TextAlignment="Center" /> </Border> <Border Grid.Column="1"> <TextBlock Grid.Column="1" Text="Experiment 2" TextAlignment="Center" /> </Border> </Grid> <Grid Grid.Row="2"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Border Grid.Column="0"> <TextBlock Grid.Column="1" Text="Mode 1" TextAlignment="Center" /> </Border> <Border Grid.Column="1"> <TextBlock Grid.Column="1" Text="Mode 2" TextAlignment="Center" /> </Border> <Border Grid.Column="2"> <TextBlock Grid.Column="1" Text="Mode 1" TextAlignment="Center" /> </Border> <Border Grid.Column="4"> <TextBlock Grid.Column="1" Text="Mode 2" TextAlignment="Center" /> </Border> </Grid> <Grid Grid.Row="3"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Border Grid.Column="0"> <TextBlock Grid.Column="1" Text="Mode 1" TextAlignment="Center" /> </Border> <Border Grid.Column="1"> <TextBlock Grid.Column="1" Text="Mode 2" TextAlignment="Center" /> </Border> <Border Grid.Column="2"> <TextBlock Grid.Column="1" Text="Mode 1" TextAlignment="Center" /> </Border> <Border Grid.Column="4"> <TextBlock Grid.Column="1" Text="Mode 2" TextAlignment="Center" /> </Border> </Grid> <DataGrid Name="datagrid1" AutoGenerateColumns="False" Grid.Row="3" RowHeaderWidth="10" Loaded="datagrid1_Loaded"> <DataGrid.Columns> <DataGridTextColumn x:Name="Column1" Binding="{Binding Name}" Header="column 1" Width="100" /> <DataGridTextColumn x:Name="Column2" Binding="{Binding Age}" Header="column 2" Width="80" /> <DataGridTextColumn x:Name="Column3" Binding="{Binding Sample}" Header="column 3" Width="80" /> <DataGridTextColumn x:Name="Column4" Binding="{Binding Sample}" Header="column 4" Width="*" /> </DataGrid.Columns> </DataGrid></Grid></Window>
Output
If you want, you can set the ColumnDefinition Width
of a Grid
, like a DataGrid
column:
<Grid.ColumnDefinitions> <ColumnDefinition Width="{Binding ElementName=SampleDataGrid, Path=RowHeaderWidth}" /> <ColumnDefinition Width="{Binding ElementName=Column1, Path=ActualWidth}" /> <ColumnDefinition Width="{Binding ElementName=Column2, Path=ActualWidth}" /></Grid.ColumnDefinitions>
Also, you need to define the same Style
for the Grid
header and DataGrid
.
<DataGrid> <DataGrid.Columns> <DataGridTemplateColumn Width="400"> <DataGridTemplateColumn.Header> <StackPanel Width="400" HorizontalAlignment="Center"> <Label HorizontalContentAlignment="Center" FontWeight="Bold">EXPERIMENT 1</Label> <Line Stroke="Black" X1="0" X2="400" Y1="0" Y2="0" /> <StackPanel Width="400" Orientation="Horizontal"> <Label Width="200" HorizontalContentAlignment="Center">MODE 1</Label> <Line Stroke="Black" X1="1" X2="1" Y1="0" Y2="26" /> <Label Width="200" HorizontalContentAlignment="Center">MODE 2</Label> </StackPanel> <Line Stroke="Black" X1="0" X2="400" Y1="0" Y2="0" /> <StackPanel Width="400" Orientation="Horizontal"> <Label Width="100" HorizontalContentAlignment="Center">VALUE 1</Label> <Line Stroke="Black" X1="1" X2="1" Y1="0" Y2="26" /> <Label Width="100" HorizontalContentAlignment="Center">VALUE 2</Label> <Line Stroke="Black" X1="1" X2="1" Y1="0" Y2="26" /> <Label Width="100" HorizontalContentAlignment="Center">VALUE 1</Label> <Line Stroke="Black" X1="1" X2="1" Y1="0" Y2="26" /> <Label Width="100" HorizontalContentAlignment="Center">VALUE 2</Label> </StackPanel> </StackPanel> </DataGridTemplateColumn.Header> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Width="400" Orientation="Horizontal"> <ComboBox Width="100" /> <ComboBox Width="100" /> <ComboBox Width="100" /> <ComboBox Width="100" /> </StackPanel> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Width="400"> <DataGridTemplateColumn.Header> <StackPanel Width="400" HorizontalAlignment="Center"> <Label HorizontalContentAlignment="Center" FontWeight="Bold">EXPERIMENT 2</Label> <Line Stroke="Black" X1="0" X2="400" Y1="0" Y2="0" /> <StackPanel Width="400" Orientation="Horizontal"> <Label Width="200" HorizontalContentAlignment="Center">MODE 1</Label> <Line Stroke="Black" X1="1" X2="1" Y1="0" Y2="26" /> <Label Width="200" HorizontalContentAlignment="Center">MODE 2</Label> </StackPanel> <Line Stroke="Black" X1="0" X2="400" Y1="0" Y2="0" /> <StackPanel Width="400" Orientation="Horizontal"> <Label Width="100" HorizontalContentAlignment="Center">VALUE 1</Label> <Line Stroke="Black" X1="1" X2="1" Y1="0" Y2="26" /> <Label Width="100" HorizontalContentAlignment="Center">VALUE 2</Label> <Line Stroke="Black" X1="1" X2="1" Y1="0" Y2="26" /> <Label Width="100" HorizontalContentAlignment="Center">VALUE 1</Label> <Line Stroke="Black" X1="1" X2="1" Y1="0" Y2="26" /> <Label Width="100" HorizontalContentAlignment="Center">VALUE 2</Label> </StackPanel> </StackPanel> </DataGridTemplateColumn.Header> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Width="400" Orientation="Horizontal"> <ComboBox Width="100" /> <ComboBox Width="100" /> <ComboBox Width="100" /> <ComboBox Width="100" /> </StackPanel> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>