如何将 WPF DataGrid 列的默认排序方向设置为降序?
How to set default sort direction to descending for WPF DataGrid column?
我有一个带有可排序列的 WPF DataGrid。我不想 pre-sort 任何特定列上的网格。我只希望当用户首次单击列 header 时的默认排序方向是降序而不是升序。
CollectionViewSource 上的 SortDescription.Direction 和 DataGridTextColumns 的 SortDirection 属性 都不会影响更改排序列时的默认排序方向。它总是在第一次单击列时选择升序 header。
99% 的时间它需要在用户工作流程中降序和切换列是频繁的,所以这增加了很多不必要的点击。我非常喜欢 XAML 解决方案(如果有的话),但如有必要,我会在事件中使用代码技巧。
如果不对排序处理程序进行少量干预,您似乎无法做到这一点,因为 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) {
// 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);
}
}
然后在你的 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
绑定到您的模型。
我有一个带有可排序列的 WPF DataGrid。我不想 pre-sort 任何特定列上的网格。我只希望当用户首次单击列 header 时的默认排序方向是降序而不是升序。
CollectionViewSource 上的 SortDescription.Direction 和 DataGridTextColumns 的 SortDirection 属性 都不会影响更改排序列时的默认排序方向。它总是在第一次单击列时选择升序 header。
99% 的时间它需要在用户工作流程中降序和切换列是频繁的,所以这增加了很多不必要的点击。我非常喜欢 XAML 解决方案(如果有的话),但如有必要,我会在事件中使用代码技巧。
如果不对排序处理程序进行少量干预,您似乎无法做到这一点,因为 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) {
// 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);
}
}
然后在你的 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
绑定到您的模型。