【问题标题】:How to force DataGrid group order in WPF?如何在 WPF 中强制 DataGrid 组顺序?
【发布时间】:2012-04-27 15:33:23
【问题描述】:

我有这样的代码:

StatusItems = new ObservableCollection<StatusItem> { };
StatusItemsGrouped = new ListCollectionView(StatusItems);
StatusItemsGrouped.GroupDescriptions.Add(new PropertyGroupDescription("GenericStatus"));
StatusItemsGrouped.SortDescriptions.Add(new SortDescription("GenericStatus", ListSortDirection.Descending));

基本上,我根据名为GenericStatus 的信息对DataGrid 上的数据进行分组。一切都很好,除了排序。我现在想要实现的是按降序对组进行排序(就像我的代码一样),但是上面代码的问题是,一旦用户单击某个列,排序就会被破坏。

我想保留组排序,但仍然允许用户排序​​。我猜用户排序基本上是次要排序,即我想要这个:ORDER BY GenericStatus DESC, UsersColumnOfChoise ASC/DESC。

【问题讨论】:

    标签: c# wpf datagrid


    【解决方案1】:

    我自己也遇到了这个问题,我的解决方案是拦截Sorting事件,让ICollectionView在ViewModel中进行排序,而不是依赖DataGrid来处理。

    XAML:

    <DataGrid ItemsSource="{Binding StatusItemsGrouped}" Sorting="OnSorting_"/>
    

    XAML.CS:

    private void OnSorting_(object sender, DataGridSortingEventArgs e)
    {
        var viewModel = DataContext as ViewModel;
        e.Handled = true;                                 // prevent DataGrid from sorting
        viewModel.SortItemSource(e.Column);               // perform sorting
        e.Column.SortDirection = viewModel.SortDirection; // set sort direction icon on column header
    }
    

    视图模型:

    public class ViewModel 
    {
        public ListCollectionView StatusItemsGrouped { get; set; }
        public ListSortDirection SortDirection { get; set; }
        public string SortColumn { get; set; }
    
        public void SortItemSource(string columnName)
        {
            if (String.Compare(SortColumn, columnName, true) == 0)
                SortDirection = ListSortDirection.Ascending;
            else
                SortDirection = ListSortDirection.Descending;
            SortColumn = columnName;
            using(StatusItemsGrouped.DeferRefresh()) {
                StatusItemsGrouped.GroupDescriptions.Clear();
                StatusItemsGrouped.SortDescriptions.Clear();
                StatusItemsGrouped.SortDescriptions.Add(new SortDescription(SortColumn, SortDirection));
                StatusItemsGrouped.GroupDescriptions.Add(new PropertyGroupDescription("GenericStatus"));
            }
            StatusItemsGrouped.Refresh();
        }
    }
    

    【讨论】:

    • 一个很好的答案。我对它进行了大量修改以供我使用,但它引导我找到了解决方案。谢谢!
    【解决方案2】:

    您可以尝试将每列单击设置为“命令” - 然后观察要执行的命令并将其添加为已排序的列,以及您的 GenericStatus。

    创建一个 CommandStub:

    private bool sortAscending;
    private CommandStub _sortList;
    public ICommand sortList {
        get {
            if (_sortList == null) {
               _sortList = new CommandStub();
               _sortList.OnExecuting += new CommandStub.ExecutingEventHandler(_sortList_OnExecuting);
            }
    
            return _sortList;
       }
    }
    
    void _sortList_OnExecuting(object parameter) {
    
        var sortColumn = (string)parameter;
        StatusItems.SortDescriptions.Clear();
    
        if (sortAscending) {
            // Always sort first by GenericStatus
            StatusItems.SortDescriptions.Add(new SortDescription("GenericStatus", ListSortDirection.Ascending));
    
            // Sort by the column clicked
            StatusItems.SortDescriptions.Add(new SortDescription(sortColumn, ListSortDirection.Ascending));
            this.sortAscending = false;
        } else {
            // Always sort first by GenericStatus
            StatusItems.SortDescriptions.Add(new SortDescription("GenericStatus", ListSortDirection.Descending));
    
            StatusItems.SortDescriptions.Add(new SortDescription(sortColumn, ListSortDirection.Descending));
            this.sortAscending = true;
        }
    }
    

    每个列标题都有一个与之关联的命令,当用户单击排序时会调用该命令:

    var h = new GridViewColumnHeader();
    h.Command = sortList;
    h.CommandParameter = "deviceName";
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-05
      • 2013-05-20
      • 2016-04-29
      • 2020-05-15
      • 2011-12-16
      • 2014-03-12
      • 2011-11-27
      • 2011-12-03
      相关资源
      最近更新 更多