如何将 WPF DataGrid 列的默认排序方向设置为降序?

Dan*_*ter 4 wpf xaml wpfdatagrid

我有一个带有可排序列的 WPF DataGrid。我不想在任何特定列上预先排序网格。我只希望用户第一次单击列标题时的默认排序方向是降序而不是升序。

更改排序列时,CollectionViewSource 上的 SortDescription.Direction 和 by DataGridTextColumns 的 SortDirection 属性都不会影响默认排序方向。它总是在第一次单击列标题时选择升序。

99% 的时间都需要降序,用户工作流中的列切换是频繁的,因此这增加了很多不必要的点击。如果有 XAML 解决方案,我非常喜欢 XAML 解决方案,但如有必要,我会在事件上使用代码技巧。

Evk*_*Evk 5

如果不对排序处理程序进行少量干预,您似乎无法做到这一点,因为 DataGrid 完成的默认排序是这样开始的:

ListSortDirection direction = ListSortDirection.Ascending;
ListSortDirection? sortDirection = column.SortDirection;
if (sortDirection.HasValue && sortDirection.Value == ListSortDirection.Ascending)
    direction = ListSortDirection.Descending;
Run Code Online (Sandbox Code Playgroud)

因此,仅当列之前已排序,并且该排序为升序时 - 它会将其翻转为降序。但是,通过小小的 hack,您可以实现您想要的。首先订阅 DataGrid.Sorting 事件,然后:

private void OnSorting(object sender, DataGridSortingEventArgs e) {
    if (e.Column.SortDirection == null)
         e.Column.SortDirection = ListSortDirection.Ascending;
    e.Handled = false;
}
Run Code Online (Sandbox Code Playgroud)

所以基本上如果还没有排序 - 你将它切换到Ascending并将它传递给默认排序DataGrid(通过设置e.Handledfalse)。在排序开始时,它会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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在你的 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>
Run Code Online (Sandbox Code Playgroud)

所以基本上你DataGridSortDesc=true,标记自己来订阅排序事件,然后你标记你需要排序的列。SortDesc如果逻辑确定存在,您还可以绑定到您的模型。