Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Showing multiple headers in one column with DataGrid

I would like to have more than one property in a column like the following:

DataGrid with more than one header in a column.

Now, it's easy to create a cell template to show more than one property, but how would one go about creating a header template that shows more than one property that still lets you sort by clicking on them? So you should be able to sort by first name just by clicking on First Name header, and same goes for all the other properties.

like image 417
hattenn Avatar asked Oct 04 '22 01:10

hattenn


1 Answers

You can use two TextBlock. In Tag property you should transfer name of the property from your data class. This string from Tag property you will use to set SortMemberPath. In the event MouseLeftButtonDown you can get from Tag property name of the actual sort property and assign it to SortMemberPath.

<DataGrid Name="dataGrid1" ItemsSource="{Binding}" AutoGenerateColumns="False" Margin="0,0,0,52">
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.HeaderTemplate >
                <DataTemplate>
                    <Grid ShowGridLines="True">
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <TextBlock Text="First Name" Tag="FirstName" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" />
                        <TextBlock Text="Last Name" Grid.Row="1" Tag="LastName" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" />                                
                    </Grid>        
                </DataTemplate>
            </DataGridTemplateColumn.HeaderTemplate>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <TextBox Text="{Binding FirstName}"/>
                        <TextBox Text="{Binding LastName}" Grid.Row="1" />
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Header="Age" Binding="{Binding Age}" />
    </DataGrid.Columns>
</DataGrid>

Code-behind:

private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    TextBlock s = sender as TextBlock;
    string sortPath = s.Tag as string;
    dataGrid1.Columns[0].SortMemberPath = sortPath;
}

You can also add TextBlock style if you want to show which property is currently sorting property and bold it font.

<DataGridTemplateColumn.HeaderTemplate >
    <DataTemplate>
        <Grid ShowGridLines="True">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <TextBlock Text="First Name" Tag="FirstName" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown">
                <TextBlock.Style>
                    <Style TargetType="TextBlock">
                        <Setter Property="FontWeight" Value="Normal" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=Columns[0].SortMemberPath, ElementName=dataGrid1}">
                                <DataTrigger.Value>
                                    <sys:String>FirstName</sys:String>
                                </DataTrigger.Value>
                                <Setter Property="FontWeight" Value="Bold" />
                            </DataTrigger>                             
                        </Style.Triggers>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
            <TextBlock Text="Last Name" Grid.Row="1" Tag="LastName" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" >
                <TextBlock.Style>
                    <Style TargetType="TextBlock">
                        <Setter Property="FontWeight" Value="Normal" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=Columns[0].SortMemberPath, ElementName=dataGrid1}">
                                <DataTrigger.Value>
                                    <sys:String>LastName</sys:String>
                                </DataTrigger.Value>
                                <Setter Property="FontWeight" Value="Bold" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </Grid>        
    </DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>

Where sys is following namespace:

xmlns:sys="clr-namespace:System;assembly=mscorlib"
like image 148
kmatyaszek Avatar answered Oct 13 '22 10:10

kmatyaszek