Multilevel column header for DataGrid in WPF Multilevel column header for DataGrid in WPF wpf wpf

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

enter image description here

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.


This is the output of the xaml

    <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>