关于C#:排序组合集合

关于C#:排序组合集合

Sorting a composite collection

因此WPF不支持CompositeCollections视图的标准排序或筛选行为,因此解决此问题的最佳做法是。

有两个或多个不同类型的对象集合。您希望将它们组合成一个可排序和可过滤的集合(不必手动实现排序或过滤器)。

我考虑过的一种方法是创建一个仅包含几个核心属性的新对象集合,包括我希望对集合进行排序的那些属性以及每种类型的对象实例。

1
2
3
4
5
6
7
8
9
class MyCompositeObject
{
    enum           ObjectType;
    DateTime       CreatedDate;
    string         SomeAttribute;
    myObjectType1  Obj1;
    myObjectType2  Obj2;
{
class MyCompositeObjects : List<MyCompositeObject> { }

然后遍历我的两个对象集合以构建新的复合集合。显然,这有点蛮力,但是可以用。我将在新的复合对象集合上获得所有默认的视图排序和过滤行为,并且能够在其上放置一个数据模板,以根据该复合项目中实际存储的类型正确显示我的列表项。

对于以更优雅的方式执行此操作有什么建议?


更新:我发现了一个更优雅的解决方案:

1
2
3
4
5
6
7
class MyCompositeObject
{
    DateTime    CreatedDate;
    string      SomeAttribute;
    Object      Obj1;
{
class MyCompositeObjects : List<MyCompositeObject> { }

我发现由于反射,存储在Obj1中的特定类型在运行时被解析,并且特定类型的DataTemplate可以按预期应用!


我对WPF不太熟悉,但是我认为这是有关对List<T>集合进行排序和筛选的问题。

(withing having to manually implement sort or filter)

您会重新考虑实现自己的排序或过滤器功能吗?根据我的经验,它很容易使用。下面的示例使用匿名委托,但是您可以轻松定义自己的方法或类来实现复杂的排序或过滤器。这样的类甚至可以具有用于动态配置和更改排序和过滤器的属性。

List<T>.Sort(Comparison<T> comparison)与自定义比较功能一起使用:

1
2
3
4
5
6
7
8
9
// Sort according to the value of SomeAttribute
List<MyCompositeObject> myList = ...;
myList.Sort(delegate(MyCompositeObject a, MyCompositeObject b)
{
    // return -1 if a < b
    // return 0 if a == b
    // return 1 if a > b
    return a.SomeAttribute.CompareTo(b.SomeAttribute);
};

一种类似的方法,用于从列表中获取项目的子集合。

List<T>.FindAll(Predicate<T> match)与自定义过滤器功能一起使用:

1
2
3
4
5
6
// Select all objects where myObjectType1 and myObjectType2 are not null
myList.FindAll(delegate(MyCompositeObject a)
{
    // return true to include 'a' in the sub-collection
    return (a.myObjectType1 != null) && (a.myObjectType2 != null);
}

您提到的

"蛮力"方法实际上是理想的解决方案。请注意,所有对象都在RAM中,没有I / O瓶颈,因此您可以在不到一秒钟的时间内在任何现代计算机上进行数百万个对象的排序和筛选。

使用集合的最优雅的方法是.NET 3.5中的System.Linq命名空间。

Thanks - I also considered LINQ to
objects, but my concern there is loss
of flexibility for typed data
templates, which I need to display the
objects in my list.

如果您目前无法预测人们将如何对对象集合进行排序和筛选,则应查看System.Linq.Expressions命名空间,以在运行时按需构建Lambda表达式(首先让用户构建表达式,然后进行编译,运行,最后使用反射名称空间来枚举结果。将头缠绕在它上面是比较棘手的,但是它是非常宝贵的功能,可能(对我而言是绝对的)比LINQ本身更具突破性的功能。


推荐阅读