Search code examples
c#wpfdatagriddatagridcolumnheader

WPF C#, Datagrid with multi level header


Good day.

Please I need to create a datagrid that looks like this screenshot

enter image description here

I found some code that gives direction on how to do similar, but I'm a bit lost in the implementation.

Here is the code which I'm trying to edit

<DataGrid ItemsSource="{Binding }" Name="dataGrid1" AutoGenerateColumns="False" 
                          ColumnHeaderHeight="50" >
                <DataGrid.Resources>

                    <Style x:Key="DataGridColumnHeader" TargetType="{x:Type DataGridColumnHeader}">
                        <Setter Property="VerticalContentAlignment" Value="Center" />
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                                    <Grid>
                                        <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" />
                                    </Grid>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>

                </DataGrid.Resources>
                <DataGrid.Columns>
                        <DataGridTextColumn  Header="Main1" Width="60" 
                                            HeaderStyle="{StaticResource DataGridColumnHeader}">
                        <DataGridTextColumn.HeaderTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Vertical">
                                    <TextBlock   Width="60"/>

                                    <DataGridColumnHeader Content="Nested1" Width="60"/>
                                </StackPanel>
                            </DataTemplate>
                        </DataGridTextColumn.HeaderTemplate>
                    </DataGridTextColumn>
                    <DataGridTextColumn Header="Nested2" Width="60"
                                             HeaderStyle="{StaticResource DataGridColumnHeader}">
                        <DataGridTextColumn.HeaderTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Vertical">
                                    <TextBlock FontWeight="Bold" Text="Main1"/>

                                    <DataGridColumnHeader Content="Nested2" Width="60" />
                                </StackPanel>
                            </DataTemplate>
                        </DataGridTextColumn.HeaderTemplate>
                    </DataGridTextColumn>
                    <DataGridTextColumn Width="60"
                                             HeaderStyle="{StaticResource DataGridColumnHeader}">
                        <DataGridTextColumn.HeaderTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Vertical">
                                    <TextBlock />

                                    <DataGridColumnHeader Content="Nested3" Width="60"/>
                                </StackPanel>
                            </DataTemplate>
                        </DataGridTextColumn.HeaderTemplate>
                    </DataGridTextColumn>
                </DataGrid.Columns>
            </DataGrid>

I edited the code to this

   <DataGrid Grid.Column="2" 
                  Grid.Row="1" Grid.RowSpan="2"
                  Height="100"
                  x:Name="assetListGrid"
                          HorizontalAlignment="Stretch"
                          VerticalAlignment="Top"
                          Margin="10 10 20 20" 
                          Background="{StaticResource ForegroundLightBrush}"
                          LoadingRow="AddIndexNumberWhenLoadingRow" 
                          BorderThickness="1"
                                 VerticalScrollBarVisibility="Auto"
                          AutoGenerateColumns="False"
                          ItemsSource="{Binding AssetList, Mode=TwoWay}" 
                          >

            <DataGrid.Resources>

                <Style x:Key="DataGridColumnHeader" TargetType="{x:Type DataGridColumnHeader}">
                    <Setter Property="VerticalContentAlignment" Value="Center" />
                    <Setter Property="Background" Value="{StaticResource WordBlueBrush}" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                                <Grid Background="{StaticResource WordBlueBrush}">
                                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" />
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>

            </DataGrid.Resources>

            <DataGrid.Columns>
                <DataGridTextColumn  Header="Asset" 
                                            HeaderStyle="{StaticResource DataGridColumnHeader}">
                    <DataGridTextColumn.HeaderTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical">
                                <TextBlock  FontSize="{StaticResource FontSizeLarge}"
                                            FontFamily="{StaticResource LatoBold}"
                                            />

                                <DataGridColumnHeader Content="Asset Number"/>
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTextColumn.HeaderTemplate>
                </DataGridTextColumn>


                <DataGridTextColumn Header="Name" 
                                             HeaderStyle="{StaticResource DataGridColumnHeader}">
                    <DataGridTextColumn.HeaderTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical">
                                <TextBlock  FontSize="{StaticResource FontSizeLarge}"
                                            FontFamily="{StaticResource LatoBold}" Text="Asset"/>

                                <DataGridColumnHeader  Content="Name"  />
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTextColumn.HeaderTemplate>
                </DataGridTextColumn>

                <DataGridTextColumn 
                                             HeaderStyle="{StaticResource DataGridColumnHeader}">
                    <DataGridTextColumn.HeaderTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical">
                                <TextBlock />

                                <DataGridColumnHeader Content="Role" />
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTextColumn.HeaderTemplate>
                </DataGridTextColumn>

                <DataGridTextColumn 
                                             HeaderStyle="{StaticResource DataGridColumnHeader}">
                    <DataGridTextColumn.HeaderTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical">
                                <TextBlock />

                                <DataGridColumnHeader Content="Comment" />
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTextColumn.HeaderTemplate>
                </DataGridTextColumn>

                <DataGridTextColumn 
                                             HeaderStyle="{StaticResource DataGridColumnHeader}">
                    <DataGridTextColumn.HeaderTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical">
                                <TextBlock />

                                <DataGridColumnHeader Content="Creation TimeStamp" />
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTextColumn.HeaderTemplate>
                </DataGridTextColumn>
            </DataGrid.Columns>

            <DataGridTextColumn 
                                             HeaderStyle="{StaticResource DataGridColumnHeader}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock />

                            <DataGridColumnHeader Content="Location" />
                        </StackPanel>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>

            <DataGridTextColumn 
                                             HeaderStyle="{StaticResource DataGridColumnHeader}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock />
                            <DataGridColumnHeader Content="Value" />
                        </StackPanel>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>



        </DataGrid>

And here is the result

enter image description here

I don't know how to add the next top column ( Manufacturer and its sub columns) The sub columns of "Asset" looks like a gig-zaw and I can't figure out how to even them out. I have tried to add thesame heights to all column headers to no avail.

Moreover, I'm also finding it hard to modify the cell template and bind it to a particular property in my viewmodel. This is because some of the cells will contain both a textbox and a button.

Can anyone be kind enough to direct me on how to

  1. Even out the heights of the subcolumn headers
  2. Add the 2nd top column
  3. Override the cell template for a single column to contain a button and a text block? enter code here

Solution

  • Here is the answer to couple of questions

    1. Even out the heights of the subcolumn headers

    You are missing fonts on Role, Comment, Creation Timestamp columns

    FontSize="{StaticResource FontSizeLarge}" FontFamily="{StaticResource LatoBold}"
    
    1. Add the 2nd top column

    You just have to follow the same pattern of design for the next set of columns

    <DataGrid Grid.Column="2" 
              Grid.Row="1" Grid.RowSpan="2"
              Height="100"
              x:Name="assetListGrid"
                      HorizontalAlignment="Stretch"
                      VerticalAlignment="Top"
                      Margin="10 10 20 20" 
                      BorderThickness="1"
                             VerticalScrollBarVisibility="Auto"
                      AutoGenerateColumns="False"
                      ItemsSource="{Binding AssetList, Mode=TwoWay}" 
                      >
    
        <DataGrid.Resources>
    
            <Style x:Key="DataGridColumnHeader" TargetType="{x:Type DataGridColumnHeader}">
                <Setter Property="VerticalContentAlignment" Value="Center" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                            <Grid >
                                <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" />
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
    
        </DataGrid.Resources>
    
        <DataGrid.Columns>
            <DataGridTextColumn  Header="Asset" 
                                        HeaderStyle="{StaticResource DataGridColumnHeader}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock/>
                            <DataGridColumnHeader Content="Asset Number"/>
                        </StackPanel>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
    
    
            <DataGridTextColumn Header="Name" 
                                         HeaderStyle="{StaticResource DataGridColumnHeader}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="Asset"/>
                            <DataGridColumnHeader  Content="Name"  />
                        </StackPanel>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
    
            <DataGridTextColumn 
                                         HeaderStyle="{StaticResource DataGridColumnHeader}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock />
    
                            <DataGridColumnHeader Content="Role" />
                        </StackPanel>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
    
            <DataGridTextColumn 
                                         HeaderStyle="{StaticResource DataGridColumnHeader}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock />
    
                            <DataGridColumnHeader Content="Comment" />
                        </StackPanel>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
    
            <DataGridTextColumn 
                                         HeaderStyle="{StaticResource DataGridColumnHeader}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock />
    
                            <DataGridColumnHeader Content="Creation TimeStamp" />
                        </StackPanel>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
            <DataGridTextColumn  Header="Asset" 
                                        HeaderStyle="{StaticResource DataGridColumnHeader}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock/>
                            <DataGridColumnHeader Content="Asset Number"/>
                        </StackPanel>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
    
    
            <DataGridTextColumn Header="Name" 
                                         HeaderStyle="{StaticResource DataGridColumnHeader}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="Manufacturer "/>
                            <DataGridColumnHeader  Content="Name"  />
                        </StackPanel>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
    
            <DataGridTextColumn 
                                         HeaderStyle="{StaticResource DataGridColumnHeader}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock />
    
                            <DataGridColumnHeader Content="Role" />
                        </StackPanel>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
    
            <DataGridTextColumn 
                                         HeaderStyle="{StaticResource DataGridColumnHeader}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock />
    
                            <DataGridColumnHeader Content="Comment" />
                        </StackPanel>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
    
            <DataGridTextColumn 
                                         HeaderStyle="{StaticResource DataGridColumnHeader}">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock />
    
                            <DataGridColumnHeader Content="Creation TimeStamp" />
                        </StackPanel>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
            </DataGridTextColumn>
        </DataGrid.Columns>
    
        <DataGridTextColumn 
                                         HeaderStyle="{StaticResource DataGridColumnHeader}">
            <DataGridTextColumn.HeaderTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <TextBlock />
    
                        <DataGridColumnHeader Content="Location" />
                    </StackPanel>
                </DataTemplate>
            </DataGridTextColumn.HeaderTemplate>
        </DataGridTextColumn>
    
        <DataGridTextColumn 
                                         HeaderStyle="{StaticResource DataGridColumnHeader}">
            <DataGridTextColumn.HeaderTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <TextBlock />
                        <DataGridColumnHeader Content="Value" />
                    </StackPanel>
                </DataTemplate>
            </DataGridTextColumn.HeaderTemplate>
        </DataGridTextColumn>
    </DataGrid>
    

    Hope it helps.