如何在WPF中强制DataGrid组顺序?

时间:2012-04-27 15:33:23

标签: c# wpf datagrid

我有这样的代码:

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

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

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

2 个答案:

答案 0 :(得分:3)

我自己遇到了这个问题,我的解决方法是拦截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();
    }
}

答案 1 :(得分:1)

您可以尝试将每个列单击设置为“命令” - 然后观察要执行的命令,并将其添加为排序列,以及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";
相关问题