看起来您不能不对排序处理程序进行轻微干预就完成它,因为DataGrid默认的排序是这样开始的:
ListSortDirection direction = ListSortDirection.Ascending
ListSortDirection? sortDirection = column.SortDirection
if (sortDirection.HasValue && sortDirection.Value == ListSortDirection.Ascending)
direction = ListSortDirection.Descending
只有当列在之前排序过且该排序是升序的情况下,它才会将其翻转为降序。但是通过小小的技巧,你可以实现你想要的效果。首先订阅DataGrid.Sorting事件,在那里:
private void OnSorting(object sender, DataGridSortingEventArgs e) {
if (e.Column.SortDirection == null)
e.Column.SortDirection = ListSortDirection.Ascending
e.Handled = false
}
基本上,如果还没有排序 - 您将其切换为
Ascending
并将其传递给
DataGrid
的默认排序(通过将
e.Handled
设置为
false
)。在排序开始时,它会为您翻转到
Descending
,这正是您想要的。
您可以通过使用附加属性在 XAML 中完成此操作,如下所示:
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) {
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);
}
}
然后在你的 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>
所以基本上,您可以使用
SortDesc = true
标记
DataGrid
本身,以订阅排序事件,然后仅标记需要按降序排序的列。如果有逻辑来确定这一点,还可以将
SortDesc
绑定到您的模型。
e.NewValue
订阅/取消订阅Sorting
事件处理程序,这意味着将 lambda 移动到命名的静态方法中。2)为什么在代码中设置Ascending
?难道不应该是Descending
吗? - Drew Noakes