Предварительная сортировка DataGrid в WPF

У меня есть приложение DataGrid в WPF с несколькими столбцами, включая столбец Имя. Если пользователи переключаются на конкретное представление, я хочу, чтобы данные были предварительно отсортированы по имени (и я бы хотел, чтобы в заголовке имени отображалась стрелка сортировки, как если бы пользователь щелкнул этот заголовок). Однако я не могу найти ожидаемых свойств, чтобы это произошло. Я искал что-то вроде SortColumn, SortColumnIndex, SortDirection и т. Д.

Можно ли указать столбец сортировки и направление по умолчанию в разметке (XAML) или это не поддерживается WPF Toolkit DataGrid?


person devuxer    schedule 26.10.2009    source источник
comment
Поскольку WPF не имеет встроенного DataGrid, можем ли мы предположить, что вы имеете в виду DataGrid, который поставляется с WPF Toolkit (codeplex.com/wpf) ???   -  person Drew Marsh    schedule 26.10.2009
comment
Да, я поставил тег wpftoolkit, но, наверное, не упомянул об этом в своем вопросе. Я добавлю это.   -  person devuxer    schedule 26.10.2009


Ответы (5)


Предполагая, что вы говорите об элементе управления WPF Toolkit DataGrid, вам нужно только установить для свойства CanUserSortColumns значение true, а затем установите свойство SortMemberPath каждого столбца DataGridColumn в DataGrid.

Что касается первоначальной сортировки коллекции, вы должны использовать CollectionViewSource и установить для нее сортировку, а затем назначить ее как ItemsSource вашего DataGrid. Если вы делаете это в XAML, это будет так же просто, как:

<Window.Resources>
    <CollectionViewSource x:Key="MyItemsViewSource" Source="{Binding MyItems}">
        <CollectionViewSource.SortDescriptions>
           <scm:SortDescription PropertyName="MyPropertyName"/>
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
</Window.Resources>

<DataGrid ItemsSource="{StaticResource MyItemsViewSource}">

</DataGrid>

ПРИМЕЧАНИЕ. префикс пространства имен «scm» сопоставляется с System.ComponentModel, где находится класс SortDescription.

xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"

РЕДАКТИРОВАТЬ: Я думаю, что достаточное количество людей получили помощь из этого сообщения, поэтому этот комментарий должен быть включен в этот ответ:

Мне пришлось использовать это, чтобы заставить его работать:

<DataGrid ItemsSource="{Binding Source={StaticResource MyItemsViewSource}}">
person Drew Marsh    schedule 26.10.2009
comment
@Drew, спасибо, но SortMemberPath просто указывает, какое поле в источнике данных соответствует какому столбцу в DataGrid. Мне нужно установить текущий столбец сортировки (и направление). Например, этот DataGrid в настоящее время отсортирован по имени по возрастанию. - person devuxer; 26.10.2009
comment
Вот как вы решаете проблему щелчка по столбцу заголовка и сортировки. Я случайно упустил, как изначально отсортировать сетку, сейчас добавлю к своему ответу. - person Drew Marsh; 26.10.2009
comment
Да :) Это намного ближе к тому, что я искал, спасибо. Единственная проблема заключается в том, что стрелка сортировки не отображается в заголовке столбца, по которому сортируется таблица. Я могу смириться с этим, но стрелка могла бы немного прояснить для пользователя, что такое столбец сортировки. Просто примечание для всех, кто пытается это сделать, вам нужна ссылка на WindowsBase, чтобы использовать System.ComponentModel. После того, как вы добавили ссылку, вам понадобится это: xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase". - person devuxer; 27.10.2009
comment
Мне пришлось использовать ‹DataGrid ItemsSource = {Binding Source = {StaticResource MyItemsViewSource}}›, чтобы заставить это работать. - person Samuel Jack; 12.05.2010

Я знаю, что это старый пост, но в дополнение к ответу Дрю Марша и в ответ на проблему DanM с отсутствием стрелок в заголовке столбца ... Вам необходимо добавить свойство SortDirection в DataGridColumn:

<DataGridTextColumn Header="Name" Binding="{Binding Name}" SortDirection="Ascending" />

Я разместил вопрос по этому поводу и через несколько дней нашел ответ:

Стрелки заголовка столбца не отображаются при сортировке DataGrid в XAML

person Matt    schedule 29.07.2011
comment
Это означает, что свойство SortDirection должно вручную соответствовать столбцам в SortDescription - есть ли способ для DataGrid обнаруживать сортировку CollectionViewSource и автоматически отображать индикаторы? - person Dai; 02.11.2017

Когда вы видите, что ItemsSource не поддерживает исключение CollectionViewSource, вы можете установить DataContext для DataGrid как «MyItemsViewSource» и ItemsSource как {Binding} следующим образом:

<DataGrid DataContext="{StaticResource MyItemsViewSource}" ItemsSource="{Binding}">
</DataGrid>
person Sukhjeet    schedule 18.12.2009
comment
Я продолжаю возвращаться к этому посту (третий раз в этом году), потому что забываю сделать эту очень важную часть / кусок головоломки! Спасибо, что разместили это. - person denis morozov; 10.07.2012

Когда вы видите ItemsSource doesn't support CollectionViewSource исключение, вы можете отсортировать коллекцию с помощью Linq, прежде чем направить ее в DataGrid:

ObservableCollection<MyDataClass> myCollection = new ObservableCollection<MyDataClass>();
dataGrid.ItemsSource = from item in myCollection orderby item select item;

Вы должны реализовать IComparable интерфейс для MyDataClass:

public class MyDataClass : IComparable<MyDataClass> {
    public int CompareTo(Classified other) {
        return other.Value.CompareTo(this.Value); // DESC
        return this.Value.CompareTo(other.Value); // ASC
    }
}
person Václav Dajbych    schedule 11.11.2009
comment
Это действительно сработало для меня, когда я пытался заказать BindlingList с помощью Lambda. Это сработало, лямбда - нет! - person DerpyNerd; 13.02.2015

У меня это работает.

ListSortDirection sortDirection;
int selectedColumnIndex;
private void customerDataGrid_Sorting(object sender, DataGridSortingEventArgs e)
{
    selectedColumnIndex = e.Column.DisplayIndex;
    sortDirection = (e.Column.SortDirection == ListSortDirection.Ascending ? ListSortDirection.Descending: ListSortDirection.Ascending);
}

private void applySortDescriptions(ListSortDirection listSortDirection)
{
    //Clear current sort descriptions 
    customerDataGrid.Items.SortDescriptions.Clear();

    //Get property name to apply sort based on desired column 
    string propertyName = customerDataGrid.Columns[selectedColumnIndex].SortMemberPath;

    //Add the new sort description 
    customerDataGrid.Items.SortDescriptions.Add(new SortDescription(propertyName, listSortDirection));

    //apply sort 
    applySortDirection(listSortDirection);

    //refresh items to display sort 
    customerDataGrid.Items.Refresh();
}

private void applySortDirection(ListSortDirection listSortDirection)
{
    customerDataGrid.Columns[selectedColumnIndex].SortDirection = listSortDirection;
}
person Pramod Pawar    schedule 29.05.2017