C# WPF DataGrid(在.NET 4.0中不是Toolkit),使用ICollectionView进行标题排序

C# WPF DataGrid(在.NET 4.0中不是Toolkit),使用ICollectionView进行标题排序,c#,.net,wpf,datagrid,C#,.net,Wpf,Datagrid,首先让我澄清一下(如果标题不够清楚):我讨论的是.NET4.0框架中的System.Windows.Controls.DataGrid,而不是工具包版本 我目前正在我的项目中构建一个小的可重用类/视图模型集/etc,以便为我的应用程序构建一个功能强大的数据网格 现在,默认情况下,给定IEnumarableItemsSource,DataGrid控件支持标题单击列排序 但是,我的实现现在使用CollectionViewSource和ICollectionView向DataGrid公开数据成员。当以

首先让我澄清一下(如果标题不够清楚):我讨论的是.NET4.0框架中的
System.Windows.Controls.DataGrid
,而不是工具包版本

我目前正在我的项目中构建一个小的可重用类/视图模型集/etc,以便为我的应用程序构建一个功能强大的数据网格

现在,默认情况下,给定
IEnumarable
ItemsSource,DataGrid控件支持标题单击列排序

但是,我的实现现在使用
CollectionViewSource
ICollectionView
向DataGrid公开数据成员。当以这种方式连接时,它似乎依赖排序描述来排序

虽然我喜欢从代码中进行控制(可以连接到各种各样的东西),但我也需要用户能够单击标题栏对结果进行排序。我正在寻找一种方法来钩住标题栏的点击,以指示我的代码适当地调整
CollectionViewSource

  • 我是否需要重新设置标题按钮的样式来触发事件
  • 有没有办法从DataGrid控件的现有标头钩住排序事件
  • 最好的办法是什么
  • 我是否错误地使用了
    ICollectionView

  • 您能否将ItemSource设置为ObservableCollection?然后,当用户单击列标题时,DataGrid将自动允许排序。

    您可以处理
    DataGrid.sorting
    事件,使用其EventArgs的“e.column”属性获取有关单击的列标题的信息,并设置“e.Handled=true”以防止DataGrid的默认排序生效。下面是一个小例子,说明了这一点:

    XAML:

    
    
    代码隐藏:

    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.ComponentModel;
    
    namespace StackOverflow
    {
        public partial class MainWindow : Window
        {
            ListCollectionView lcv;
            public MainWindow()
            {
                InitializeComponent();
    
                List<Item> items = new List<Item>();
                items.Add(new Item() { Name = "Item1", Category = "A" });
    
                items.Add(new Item() { Name = "Item5", Category = "B" });
                items.Add(new Item() { Name = "Item3", Category = "A" });
                items.Add(new Item() { Name = "Item4", Category = "B" });
                items.Add(new Item() { Name = "Item2", Category = "A" });
    
                lcv = new ListCollectionView(items);
                lcv.GroupDescriptions.Add(new PropertyGroupDescription("Category"));
    
                this.DataGrid.ItemsSource = lcv;
    
            }
    
            public class Item
            {
                public string Name { get; set; }
                public string Category { get; set; }
            }
    
            private void DataGrid_Sorting(object sender, DataGridSortingEventArgs e)
            {            
                e.Handled = true;
                lcv.SortDescriptions.Add(new SortDescription(e.Column.SortMemberPath, ListSortDirection.Ascending));
            }
        }
    }
    
    使用System.Collections.Generic;
    使用System.Windows;
    使用System.Windows.Controls;
    使用System.Windows.Data;
    使用System.Windows.Documents;
    使用系统组件模型;
    命名空间堆栈溢出
    {
    公共部分类主窗口:窗口
    {
    ListCollectionView lcv;
    公共主窗口()
    {
    初始化组件();
    列表项=新列表();
    添加(新项(){Name=“Item1”,Category=“A”});
    items.Add(newitem(){Name=“Item5”,Category=“B”});
    items.Add(newitem(){Name=“Item3”,Category=“A”});
    添加(新项(){Name=“Item4”,Category=“B”});
    添加(新项(){Name=“Item2”,Category=“A”});
    lcv=新列表集合视图(项目);
    lcv.GroupDescriptions.Add(新属性GroupDescription(“类别”);
    this.DataGrid.ItemsSource=lcv;
    }
    公共类项目
    {
    公共字符串名称{get;set;}
    公共字符串类别{get;set;}
    }
    私有void DataGrid_排序(对象发送方、DataGridSortingEventArgs e)
    {            
    e、 已处理=正确;
    lcv.SortDescriptions.Add(新的SortDescription(e.Column.SortMemberPath,ListSortDirection.升序));
    }
    }
    }
    
    实际上我找到了答案。我犯了一个大错。它源于DataGrid控件中列的设置

    必须确保在
    DataGridColumn
    上设置了
    CanUserSort=“True”
    ,并且设置了
    SortMemberPath
    属性

    例如:

                <DataGridTemplateColumn Header="Account #" Width="Auto" CanUserSort="True" SortMemberPath="AccountNum">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding AccountNum}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
    
    
    
    No,因为我需要分组,并可能在以后使用ICollectionView界面进行过滤。绑定实现IList的集合,因此List和obserrvablecollectionon:)将CanUserSort设置为true并在列上设置SortMemberPath是如何设置与datagrid的排序,而不是网格绑定到的集合。
                <DataGridTemplateColumn Header="Account #" Width="Auto" CanUserSort="True" SortMemberPath="AccountNum">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding AccountNum}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>