按组中的值对WPF DataGrid进行排序 [英] Sort a WPF DataGrid by a value within a group

查看:576
本文介绍了按组中的值对WPF DataGrid进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WPF DataGrid,它由数据库查询填充.初始结果在SQL中进行分组和排序:

I have a WPF DataGrid which is populated by a database query. The initial results are grouped and sorted in SQL:

我希望我的用户能够按任意列进行排序,但是仅按值"排序将使各组混淆.我希望这些组保持分组状态,同时按指定的列进行排序.

I'd like my users to be able to sort by arbitrary columns, however simply ordering by "Value" will mix up the groups. I want the groups to remain grouped, while being sorted by the specified column.

例如,按升序按值"列排序,应按每个组中的最小值"对进行排序.结果应该是:

For example, sorting by the column "Value", ascending, should sort the Groups by their minimum "Value" within each group. The result should be:

我已经有一个排序处理程序在工作,我怀疑Linq在这里可能有用,但是我似乎找不到找到对Value和GroupName进行排序的方法.

I've already got a sort handler working and I suspect that Linq might be useful here, but I can't seem to find a way to sort both Value and GroupName.

推荐答案

您实际上需要以以下方式实现排序处理程序(请参见代码中的注释):

You need to indeed implement sorting handler, in the following way (see the comments in code):

private void OnSorting(object sender, DataGridSortingEventArgs e) {
    if (e.Column.SortMemberPath == "Value") {
        // get view
        var source = (ListCollectionView) CollectionViewSource.GetDefaultView(this.Items);
        // manually change sort direction to the next value
        // so null > ascending > descending > back to null
        var sort = e.Column.SortDirection;
        if (sort == null)
            sort = ListSortDirection.Ascending;
        else if (sort == ListSortDirection.Ascending)
            sort = ListSortDirection.Descending;
        else
            sort = null;

        if (sort != null) {
            // first figure out correct group ordering
            var sortedGroups = dataGrid.ItemsSource.OfType<Item>()
                .GroupBy(c => c.GroupName)
                .Select(c => new {GroupName = c.Key, MinValue = c.Min(r => r.Value)})
                .OrderBy(c => c.MinValue)
                .Select(c => c.GroupName)
                .ToArray();
            // now set collection view custom sort to out comparer
            source.CustomSort = new ItemComparer(sortedGroups, sort == ListSortDirection.Ascending);
        }
        else {
            // otherwise remove custom sort and sort as usual
            source.CustomSort = null;
        }
        e.Column.SortDirection = sort;
        e.Handled = true;
    }
}

public class ItemComparer : IComparer {
    private readonly string[] _sortedGroups;
    private readonly bool _asc;

    public ItemComparer(string[] sortedGroups, bool asc) {
        _sortedGroups = sortedGroups;
        _asc = asc;
    }

    public int Compare(object ox, object oy) {
        var x = (Item) ox;
        var y = (Item) oy;

        if (x.GroupName == y.GroupName) {
            // if group names are the same - sort as usual, by Value
            return x.Value.CompareTo(y.Value) * (_asc ? 1 : -1);
        }
        // otherwise - sort by group name using the order we already figured out at previous step
        return (Array.IndexOf(_sortedGroups, x.GroupName) - Array.IndexOf(_sortedGroups, y.GroupName)) * (_asc ? 1 : -1);
    }
}

这篇关于按组中的值对WPF DataGrid进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆