Сортировка по нескольким столбцам в сетке данных WPF - PullRequest
21 голосов
/ 24 июня 2011

Как настроить сетку данных WPF для сортировки по нескольким столбцам, аналогично наличию двух сортируемых столбцов, щелкнув заголовок первого столбца для первичной сортировки, а затем SHIFT, щелкнув заголовок второго столбца для вторичной сортировки , Я бы хотел, чтобы сортировка по нескольким столбцам происходила автоматически, когда пользователь нажимает на заголовок первого столбца, не нажимая SHIFT, чтобы щелкнуть заголовок второго столбца. Есть ли способ сделать это полностью в xaml? Если нет, то как я могу сделать это в коде? В настоящее время используется VB.Net, но допустим фрагмент C #, если он у вас есть. Спасибо!

Ответы [ 2 ]

20 голосов
/ 24 июня 2011

Вы можете сделать это, добавив System.ComponentModel пространство имен, например:

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

, затем внутри CollectionViewSource XAML добавьте новый SortDescription вот так:

<CollectionViewSource … >
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="Column1"/>
                <scm:SortDescription PropertyName="Column2"/>
            </CollectionViewSource.SortDescriptions>
</CollectionViewSource>

это будет сортировать сетку данных по столбцу1, столбцу 2.

Редактировать:

и сделать это с помощью кода C # позадидовольно просто:

    private void btnSort_Click(object sender, RoutedEventArgs e)
    {
        System.Windows.Data.CollectionViewSource myViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("The_ViewSource_Name")));
        myViewSource.SortDescriptions.Add(new SortDescription("Column1", ListSortDirection.Ascending));
        myViewSource.SortDescriptions.Add(new SortDescription("Column2", ListSortDirection.Ascending));
    }

Edit2:

Временное решение может быть сделано, чтобы перехватить заголовок столбца при щелчке левой кнопкой мыши и предотвратить сортировку сетки по этому столбцу, как это:

  • Отключить свойство сетки с именем CanUserSortColumns

enter image description here

  • Добавить этот код вgrid Событие PreviewMouseLeftButtonUp:

    private void myDataGrid_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        DependencyObject dep = (DependencyObject)e.OriginalSource;
        while ((dep != null) &&
        !(dep is DataGridCell) &&
        !(dep is DataGridColumnHeader))
        {
            dep = VisualTreeHelper.GetParent(dep);
        }
    
        if (dep == null)
            return;
    
        if (dep is DataGridColumnHeader)
        {
            DataGridColumnHeader columnHeader = dep as DataGridColumnHeader;
            // check if this is the wanted column
            if (columnHeader.Column.Header.ToString() == "The_Wanted_Column_Title")
            {
                System.Windows.Data.CollectionViewSource myViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("myViewSource")));
                myViewSource.SortDescriptions.Clear();
                myViewSource.SortDescriptions.Add(new SortDescription("Column1", ListSortDirection.Ascending));
                myViewSource.SortDescriptions.Add(new SortDescription("Column2", ListSortDirection.Ascending));
            }
            else
            {
                //usort the grid on clicking on any other columns, or maybe do another sort combination
                System.Windows.Data.CollectionViewSource myViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("myViewSource")));
                myViewSource.SortDescriptions.Clear();
            }
    
        }
    }
    

Вы можете изменить и расширить этот код в соответствии с вашими требованиями.

13 голосов
/ 02 сентября 2014

Надеюсь, это поможет другим. Мое решение сохраняет функциональность сортировки по умолчанию и позволяет сортировать по нескольким столбцам.

Поместите событие сортировки в вашу сетку данных

<DataGrid x:Name="dataGridName" Sorting="dataGridName_Sorting">

А теперь в вашем коде позади

private void dataGridName_Sorting(object sender, DataGridSortingEventArgs e)
{
    var dgSender = (DataGrid) sender;
    var cView = CollectionViewSource.GetDefaultView(dgSender.ItemsSource);

    //Alternate between ascending/descending if the same column is clicked 
    ListSortDirection direction = ListSortDirection.Ascending;
    if (cView.SortDescriptions.FirstOrDefault().PropertyName == e.Column.SortMemberPath)
        direction = cView.SortDescriptions.FirstOrDefault().Direction == ListSortDirection.Descending ? ListSortDirection.Ascending : ListSortDirection.Descending;

    cView.SortDescriptions.Clear();
    AddSortColumn((DataGrid)sender, e.Column.SortMemberPath, direction);
    //To this point the default sort functionality is implemented

    //Now check the wanted columns and add multiple sort 
    if (e.Column.SortMemberPath == "WantedColumn")
    {
        AddSortColumn((DataGrid)sender, "SecondColumn", direction);
    }
    e.Handled = true;
}

private void AddSortColumn(DataGrid sender, string sortColumn, ListSortDirection direction)
{
    var cView = CollectionViewSource.GetDefaultView(sender.ItemsSource);
    cView.SortDescriptions.Add(new SortDescription(sortColumn, direction));
    //Add the sort arrow on the DataGridColumn
    foreach (var col in sender.Columns.Where(x => x.SortMemberPath == sortColumn))
    {
        col.SortDirection = direction;
    }
}

Параметр sortDirection в DataGridColumn позволяет отображать стрелку на сетке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...