I'm working on a DataGrid with a custom sort implementation and the colomnHeader should display the sort direction, and the sort order.
I'm using MVVM pattern.
In my viewModel, I have an ObservableCollection of my sorters. Each sorter has a tag, which correspond to the SortMemberPath of the column.
My goal is to bind the columnHeader to the corresponding sorter with the correct tag, in order to obtain the SortDirection (The columnHeader has it too), but also the SortOrder, which allow me to display the index of the sorter in the header. After that, I would like to add a similary feature for the Filters (with an other ObservableCollection of Filters)
To do so, I'm using a custom Thumb that I set in the header, with the following DependencyProperty :
- ListSortDirection? CustomSortDirection
- int SortOrder
- bool IsFiltered
But by using this way, I need to update the thumbs when the sorters list is modified.
<!--Custom Column Header template to show extra elements in the header-->
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<!--Let's keep the top section grid to contain the DataGridHeaderBorder, and left+right thumbs.-->
<Grid x:Name="fullHeader" Background="{StaticResource Brush.Background}" >
<Grid Margin="0">
<Grid.ColumnDefinitions>
<!--Padding-->
<ColumnDefinition Width="5" />
<!--For ContentPresenter-->
<ColumnDefinition Width="*" />
<!--Padding-->
<ColumnDefinition Width="3" />
<!--For filter symbol-->
<ColumnDefinition Width="10" />
<!--Padding-->
<ColumnDefinition Width="3" />
<!--For sort order indicator-->
<ColumnDefinition Width="12" />
<!--Padding-->
<ColumnDefinition Width="5" />
</Grid.ColumnDefinitions>
<!--Hidden rectangle is placed to be shown when mouse hovers on the column (to highlight the column.)-->
<Rectangle x:Name="HoverRectangle"
Stretch="Fill"
Grid.ColumnSpan="7"
Fill="{StaticResource Brush.BackgroundMouseOver}"
Opacity="0"
StrokeThickness="0" />
<!--Content of the header.-->
<ContentPresenter Grid.Column="1"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
Cursor="{TemplateBinding Cursor}" />
<!--Drop down filter button.-->
<!--Filter symbol-->
<Path x:Name="FilterSymbol"
Grid.Column="3"
Data="M 0,0 L 1,1 1,3 2,3 2,1 3,0 Z"
Stretch="UniformToFill"
Stroke="{TemplateBinding Foreground}"
Fill="{TemplateBinding Foreground}"
Margin="0,5" />
<!--Sort order arrow icon.-->
<Grid Grid.Column="5">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Path x:Name="SortArrow"
Grid.Row="0"
HorizontalAlignment="Center" VerticalAlignment="Center"
Width="8"
RenderTransformOrigin=".5,.5"
Visibility="Visible"
Fill="{TemplateBinding Foreground}"
Stretch="Uniform"
Data="F1 M -5.215,6.099L 5.215,6.099L 0,0L -5.215,6.099 Z" />
<TextBlock x:Name="SortOrder"
Text="{Binding ElementName=SorterThumb, Path=SortOrder}"
Grid.Row="1"
FontSize="8"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Grid>
</Grid>
<Thumb x:Name="PART_LeftHeaderGripper"
HorizontalAlignment="Left"
Style="{StaticResource ColumnHeaderGripperStyle}" />
<Thumb x:Name="PART_RightHeaderGripper"
HorizontalAlignment="Right"
Style="{StaticResource ColumnHeaderGripperStyle}" />
<local:SorterThumb x:Name="SorterThumb" Width="0" Height="0"/>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Value="{x:Null}">
<!-- Trying to get the sorter-->
<!--Binding="{Binding DataContext,
RelativeSource={RelativeSource AncestorType=DataGrid},
Converter={StaticResource SortDirectionConv},
ConverterParameter={RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type DataGridColumn},
Path=PlacementTarget.Column.SortMemberPath}}" >-->
<DataTrigger.Binding>
<Binding ElementName="SorterThumb"
Path="CustomSortDirection"/>
</DataTrigger.Binding>
<Setter TargetName="SortArrow" Property="Visibility" Value="Hidden" />
<Setter TargetName="SortOrder" Property="Visibility" Value="Hidden" />
</DataTrigger>
<DataTrigger Value="Descending">
<DataTrigger.Binding>
<Binding ElementName="SorterThumb"
Path="CustomSortDirection"/>
</DataTrigger.Binding>
<Setter TargetName="SortArrow" Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="180" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Value="False">
<DataTrigger.Binding>
<Binding ElementName="SorterThumb"
Path="IsFiltered"/>
</DataTrigger.Binding>
<Setter TargetName="FilterSymbol" Property="Visibility" Value="Hidden" />
</DataTrigger>
<Trigger Property='IsMouseOver' SourceName="fullHeader" Value='True'>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="00:00:00" Duration="00:00:00.20000"
Storyboard.TargetName="HoverRectangle"
Storyboard.TargetProperty="(UIElement.Opacity)"
To='1.0' />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="00:00:00" Duration="00:00:00.20000"
Storyboard.TargetName="HoverRectangle"
Storyboard.TargetProperty="(UIElement.Opacity)"
To='0' />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--End of custom DataGridColumnHeader template-->
I would make a DataTrigger, with a converter, by given it the Sorters collection, and the SortMemberPath in the converterParameter.
Is it possible to do it ? And how can I achieved this feature ?
Thank you for your help !