2016-05-20 131 views
1

我有一個可排序列的WPF DataGrid。我不想預先對任何特定列上的網格進行排序。當用戶第一次點擊列標題時,我只想要默認的排序方向是降序而不是升序。如何設置WPF DataGrid列的默認排序方向爲降序?

更改排序列時,CollectionViewSource上的SortDescription.Direction和DataGridTextColumns的SortDirection屬性都不會影響默認排序方向。它總是選擇一列首標點擊升序。

99%的時間需要降序並且在用戶工作流程中切換列頻繁,所以這會增加大量不必要的點擊。如果有XAML解決方案,我會非常喜歡XAML解決方案,但如果有必要的話,會採取代碼欺騙手段。

回答

1

看來你不能這樣做沒有輕微的干預分揀處理程序,因爲默認的排序由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並把它傳遞到默認(通過設置e.Handledfalse)的DataGrid排序。在排序開始時,它會將你的內容翻轉到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> 

所以基本上你標記DataGrid本身SortDesc=true,認購排序事件,然後你只標記你需要排序的列desc。您也可以將SortDesc綁定到您的模型,如果邏輯來確定這是否存在。

+0

我也來過這個解決方案,它工作正常。太糟糕了,我無法在XAML中指定它,因爲從排序事件中很難處理返回到底層綁定數據,以確定如果您需要以這種方式工作某些欄目。 – DannyMeister

+0

@DannyMeister我已經用助手附加屬性更新了我的答案,這將允許您完全在xaml中完成此操作。 – Evk

+0

這個更新使得這個確實非常有用! – DannyMeister