BindingList居然没有排序!

130 阅读1分钟

本来想通过BindingList绑定DataGridView控件,绑定以后才发现设置列排序模式对BindingList数据完全没有作用,原因是使用泛型会失去DataTable的特性,看了各种论坛里提到的方法都非常繁琐,大多是自定义实现一个BindingList<T>类以支持排序或者实现System.Collections.Generic.IComparer<T>,点开代码一看,我直呼好家伙,完全丧失了阅读的兴趣。

那怎么办呢?既然没有,我们就直接给BindingList生成一个排序方法,没有路就硬踩出一条路来。

定义

首先定义一个静态类BindingListExtensions来扩展BindingList,并在其中添加一个Sort方法来定义排序,参数有排序列表List、排序字段keySelector、排序方向direction(默认升序)。

public static void Sort<T>(this BindingList<T> list, Func<T, IComparable> keySelector, ListSortDirection direction = ListSortDirection.Ascending)

参数校验

if (list == null)
    throw new ArgumentNullException(nameof(list));
if (keySelector == null)
    throw new ArgumentNullException(nameof(keySelector));

排序

var sortedList = direction == ListSortDirection.Ascending ? 
    list.OrderBy(keySelector).ToList() : 
    list.OrderByDescending(keySelector).ToList();

更新BindingList

list.Clear(); 
foreach (var item in sortedList) 
{ 
    list.Add(item);
}

使用

BindingList<Person> people = new BindingList<Person>
{
    new Person { Name = "Alice", Age = 30 },
    new Person { Name = "Bob", Age = 25 },
    new Person { Name = "Charlie", Age = 35 }
};

// 按名称升序排序
people.Sort(p => p.Name, ListSortDirection.Ascending);

// 输出排序后的结果
foreach (var person in people)
{
    Console.WriteLine($"{person.Name}, {person.Age}");
}

// 按年龄降序排序
people.Sort(p => p.Age, ListSortDirection.Descending);

// 输出排序后的结果
foreach (var person in people)
{
    Console.WriteLine($"{person.Name}, {person.Age}");
}