在WPF数据网格中的多个列上排序

Tom*_*Tom 21 c# vb.net wpf datagrid

如何设置我的WPF数据网格以对多个列进行排序,类似于具有两个可排序的列,单击第一列的标题进行主要排序,然后单击SHIFT点击第二列的标题进行二次排序.我希望当用户点击第一列的标题时自动发生多列排序,而不必在第二列标题上单击SHIFT.有没有办法在xaml中完全执行此操作?如果不是,我怎么能在后面的代码中执行此操作?目前使用VB.Net但如果你有一个C#片段是可以接受的.谢谢!

Iss*_*Ali 20

您可以通过添加System.ComponentModel命名空间来执行此操作,如下所示:

xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
Run Code Online (Sandbox Code Playgroud)

然后在CollectionViewSource XAML 里面添加新的SortDescriptions,如下所示:

<CollectionViewSource … >
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="Column1"/>
                <scm:SortDescription PropertyName="Column2"/>
            </CollectionViewSource.SortDescriptions>
</CollectionViewSource>
Run Code Online (Sandbox Code Playgroud)

这将对column1,column2上的datagrid进行排序.

编辑:

使用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));
    }
Run Code Online (Sandbox Code Playgroud)

EDIT2:

可以使用解决方法来捕获列标题鼠标左键单击事件,并阻止网格对该列进行排序,如下所示:

  • 禁用名为CanUserSortColumns的网格属性

在此输入图像描述

  • 将此代码添加到网格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();
            }
    
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

您可以修改和扩展此代码以满足您的要求.


Gui*_*ish 13

我希望这会有助于其他人.我的解决方案保留默认排序功能并允许对多列进行排序.

在数据网格上放置一个排序事件

<DataGrid x:Name="dataGridName" Sorting="dataGridName_Sorting">
Run Code Online (Sandbox Code Playgroud)

现在在你的代码背后

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

DataGridColumn上的sortDirection允许显示网格上的箭头.