Как установить стандартное направление сортировки по убыванию для столбца WPF DataGrid?
У меня есть WPF DataGrid с сортируемыми столбцами. Я не хочу предварительно сортировать сетку по какому-либо конкретному столбцу. Я просто хочу, чтобы направление сортировки по умолчанию, когда пользователь впервые щелкает заголовок столбца, было убывающим, а не восходящим.
Ни SortDescription.Direction для CollectionViewSource, ни свойство SortDirection объекта DataGridTextColumns не влияют на направление сортировки по умолчанию при изменении столбца сортировки. Он всегда выбирает возрастание по первому щелчку заголовка столбца.
В 99% случаев это должно происходить по убыванию, и переключение столбцов в рабочем процессе пользователя происходит часто, так что это добавляет много ненужных кликов. Я бы очень предпочел решение XAML, если оно есть, но при необходимости прибегну к хитрости кода.
1 ответ
Кажется, вы не можете сделать это без небольшого вмешательства в обработчики сортировки, потому что сортировка по умолчанию, выполняемая DataGrid, начинается следующим образом:
ListSortDirection direction = ListSortDirection.Ascending;
ListSortDirection? sortDirection = column.SortDirection;
if (sortDirection.HasValue && sortDirection.Value == ListSortDirection.Ascending)
direction = ListSortDirection.Descending;
Таким образом, только если столбец был отсортирован ранее, и этот тип сортировки был Ascending - он перевернет его на 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>
Так что в основном вы отмечаете DataGrid
сам с SortDesc=true
, чтобы подписаться на событие сортировки, а затем вы отмечаете только те столбцы, которые нужно отсортировать desc. Вы также можете связать SortDesc
к вашей модели, если логика для определения этого есть.