【问题标题】:WPF DataGrid (In .NET 4.0 Not Toolkit), Header Sorting with ICollectionViewWPF DataGrid(在 .NET 4.0 Not Toolkit 中),使用 ICollectionView 进行标题排序
【发布时间】:2011-04-13 22:12:17
【问题描述】:

首先让我澄清一下(如果标题不够清楚的话):我讨论的是来自 .NET 4.0 框架的System.Windows.Controls.DataGrid不是工具包版本。

我目前正在我的项目中构建一组可重复使用的小型类/视图模型/等,以便为我的应用程序构建一个相当强大的 DataGrid。

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

但是,我的实现现在使用CollectionViewSourceICollectionView 将数据成员公开给DataGrid。当以这种方式连接时,它似乎依赖于 SortDescriptions 进行排序。

虽然我喜欢通过代码进行控制(可以与各种事物挂钩),但我还要求我的用户能够单击标题栏来对他们的结果进行排序。我正在寻找一种方法来钩住标题栏的点击以指示我的代码适当地调整CollectionViewSource

  1. 我是否必须重新设置标题按钮的样式才能触发事件?
  2. 有没有办法从 DataGrid 控件的现有标题中挂钩排序事件?
  3. 解决此问题的最佳方法是什么?
  4. 我是否错误地使用了ICollectionView

【问题讨论】:

    标签: c# .net wpf datagrid


    【解决方案1】:

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

    XAML:

    <Window x:Class="StackOverflow.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:StackOverflow"
            Title="MainWindow" Height="350" Width="525">
        <DataGrid x:Name="DataGrid" Sorting="DataGrid_Sorting" CanUserAddRows="False">
    
            <DataGrid.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}"/>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </DataGrid.GroupStyle>
    
            <DataGrid.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </DataGrid.ItemTemplate>
        </DataGrid>
    </Window>
    

    代码隐藏:

    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));
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      其实我找到了答案。我完全犯了一个错误。它源于 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>
      

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • 不,因为我需要分组,并且可能在以后使用 ICollectionView 界面进行过滤。
        • 绑定一个实现IList的集合,所以List和ObservableColleciton :)
        • 设置 CanUserSort 为 true 并设置列上的 SortMemberPath 是如何设置数据网格的排序,而不是网格绑定的集合。
        猜你喜欢
        • 2011-09-04
        • 1970-01-01
        • 2011-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-20
        • 2011-08-12
        • 1970-01-01
        相关资源
        最近更新 更多