It seems you cannot do it without minor intervention into sorting handlers, because default sorting done by DataGrid starts like this:
ListSortDirection direction = ListSortDirection.Ascending;
ListSortDirection? sortDirection = column.SortDirection;
if (sortDirection.HasValue && sortDirection.Value == ListSortDirection.Ascending)
direction = ListSortDirection.Descending;
So only if column was sorted before, and that sort was Ascending - it will flip it to Descending. However with tiny hack you can achieve what you want. First subscribe to DataGrid.Sorting event, and there:
private void OnSorting(object sender, DataGridSortingEventArgs e) {
if (e.Column.SortDirection == null)
e.Column.SortDirection = ListSortDirection.Ascending;
e.Handled = false;
}
So basically if there was no sort yet - you switch it to Ascending
and pass it to default sorting of DataGrid
(by setting e.Handled
to false
). At the beginning of sorting it will flip that to Descending
for you, which is what you want.
You can do that in xaml with a help of attached property, like this:
public static class DataGridExtensions {
public static readonly DependencyProperty SortDescProperty = DependencyProperty.RegisterAttached(
"SortDesc", typeof (bool), typeof (DataGridExtensions), new PropertyMetadata(false, OnSortDescChanged));
private static void OnSortDescChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var grid = d as DataGrid;
if (grid != null) {
grid.Sorting += (source, args) => {
if (args.Column.SortDirection == null) {
// here we check an attached property value of target column
var sortDesc = (bool) args.Column.GetValue(DataGridExtensions.SortDescProperty);
if (sortDesc) {
args.Column.SortDirection = ListSortDirection.Ascending;
}
}
};
}
}
public static void SetSortDesc(DependencyObject element, bool value) {
element.SetValue(SortDescProperty, value);
}
public static bool GetSortDesc(DependencyObject element) {
return (bool) element.GetValue(SortDescProperty);
}
}
Then in your xaml:
<DataGrid x:Name="dg" AutoGenerateColumns="False" ItemsSource="{Binding Items}" local:DataGridExtensions.SortDesc="True">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Value}"
Header="Value"
local:DataGridExtensions.SortDesc="True" />
</DataGrid.Columns>
</DataGrid>
So basically you mark DataGrid
itself with SortDesc=true
, to subscribe to sorting event, and then you mark only that columns you need to be sorted desc. You can also bind SortDesc
to your model if logic to determine this is there.