Reputation: 4399
I would like to have more than one property in a column like the following:
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.
Upvotes: 5
Views: 7414
Reputation: 136
Take a look at this example of StringFormat:
And change the header of your DataGrid column like the example below :
<DataGrid>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock.Text>
<MultiBinding StringFormat="{}{1}{0}{2}">
<Binding Source="{x:Static sys:Environment.NewLine}"/>
<Binding Path="FirstName" />
<Binding Path="LastName"/>
</MultiBinding>
</TextBlock>
</DataGridTemplateColumn.Header>
</DataGrid.Columns>
</DataGrid>
with xmlns:sys="clr-namespace:System;assembly=mscorlib"
Upvotes: 0
Reputation: 19296
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"
Upvotes: 4