DataGridView 排序和例如绑定列表<T>在.NET中 [英] DataGridView sort and e.g. BindingList&lt;T&gt; in .NET

查看:12
本文介绍了DataGridView 排序和例如绑定列表<T>在.NET中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Windows 窗体中使用了一个 BindingList,其中包含一个IComparable"联系人对象列表.现在我希望用户能够按网格中显示的任何列进行排序.

I'm using a BindingList<T> in my Windows Forms that contains a list of "IComparable<Contact>" Contact-objects. Now I'd like the user to be able to sort by any column displayed in the grid.

MSDN 在线描述了一种方法,它展示了如何基于允许排序的 BindingList 实现自定义集合.但是,是否没有 Sort 事件或可以在 DataGridView(或者甚至更好,在 BindingSource 上)捕获的东西以使用自定义代码对底层集合进行排序?

There is a way described on MSDN online which shows how to implement a custom collection based on BindingList<T> which allows sorting. But isn't there a Sort-event or something that could be caught in the DataGridView (or, even nicer, on the BindingSource) to sort the underlying collection using custom code?

我不太喜欢 MSDN 描述的方式.另一种方式是我可以轻松地将 LINQ 查询应用于集合.

I don't really like the way described by MSDN. The other way I could easily apply a LINQ query to the collection.

推荐答案

我非常感谢 Matthias 的解决方案 的简单性和美丽.

I higly appreciate Matthias' solution for its simplicity and beauty.

然而,虽然这对低数据量提供了出色的结果,但在处理大数据量时,由于反射,性能不太好.

However, while this gives excellent results for low data volumes, when working with large data volumes the performance is not so good, due to reflection.

我用一组简单的数据对象进行了测试,计算了 100000 个元素.按整数类型属性排序大约需要 1 分钟.我将要进一步详细说明的实现将其更改为 ~200 毫秒.

I ran a test with a collection of simple data objects, counting 100000 elements. Sorting by an integer type property took around 1 min. The implementation I'm going to further detail changed this to ~200ms.

基本思想是使强类型比较受益,同时保持 ApplySortCore 方法的通用性.以下代码将通用比较委托替换为在派生类中实现的对特定比较器的调用:

The basic idea is to benefit strongly typed comparison, while keeping the ApplySortCore method generic. The following replaces the generic comparison delegate with a call to a specific comparer, implemented in a derived class:

SortableBindingList 中的新内容:

New in SortableBindingList<T>:

protected abstract Comparison<T> GetComparer(PropertyDescriptor prop);

ApplySortCore 更改到:

ApplySortCore changes to:

protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
    List<T> itemsList = (List<T>)this.Items;
    if (prop.PropertyType.GetInterface("IComparable") != null)
    {
        Comparison<T> comparer = GetComparer(prop);
        itemsList.Sort(comparer);
        if (direction == ListSortDirection.Descending)
        {
            itemsList.Reverse();
        }
    }

    isSortedValue = true;
    sortPropertyValue = prop;
    sortDirectionValue = direction;
}

现在,在派生类中必须为每个可排序的属性实现比较器:

Now, in the derived class one have to implement comparers for each sortable property:

class MyBindingList:SortableBindingList<DataObject>
{
        protected override Comparison<DataObject> GetComparer(PropertyDescriptor prop)
        {
            Comparison<DataObject> comparer;
            switch (prop.Name)
            {
                case "MyIntProperty":
                    comparer = new Comparison<DataObject>(delegate(DataObject x, DataObject y)
                        {
                            if (x != null)
                                if (y != null)
                                    return (x.MyIntProperty.CompareTo(y.MyIntProperty));
                                else
                                    return 1;
                            else if (y != null)
                                return -1;
                            else
                                return 0;
                        });
                    break;

                    // Implement comparers for other sortable properties here.
            }
            return comparer;
        }
    }
}

这个变体需要更多的代码,但是,如果性能是一个问题,我认为值得付出努力.

This variant requires a little bit more code but, if performance is an issue, I think it worths the effort.

这篇关于DataGridView 排序和例如绑定列表<T>在.NET中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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