-
08-06-2019 - |
题
因此,WPF 不支持 CompositeCollections 视图的标准排序或过滤行为,那么解决此问题的最佳实践是什么。
存在两个或多个不同类型的对象集合。您希望将它们组合成一个可排序和可过滤的集合(必须手动实现排序或过滤)。
我考虑过的方法之一是创建一个仅包含几个核心属性的新对象集合,包括我希望集合排序的属性以及每种类型的对象实例。
class MyCompositeObject
{
enum ObjectType;
DateTime CreatedDate;
string SomeAttribute;
myObjectType1 Obj1;
myObjectType2 Obj2;
{
class MyCompositeObjects : List<MyCompositeObject> { }
然后循环遍历我的两个对象集合以构建新的复合集合。显然,这有点暴力的方法,但它会起作用。我将在新的复合对象集合上获得所有默认视图排序和过滤行为,并且我能够在其上放置一个数据模板,以根据该复合项目中实际存储的类型正确显示我的列表项。
有什么建议可以以更优雅的方式做到这一点?
解决方案 3
更新:我找到了一个更优雅的解决方案:
class MyCompositeObject
{
DateTime CreatedDate;
string SomeAttribute;
Object Obj1;
{
class MyCompositeObjects : List<MyCompositeObject> { }
我发现由于反射,存储在 Obj1 中的特定类型在运行时被解析,并且类型特定的 DataTemplate 按预期应用!
其他提示
我还不太熟悉 WPF,但我认为这是一个有关排序和过滤的问题 List<T>
收藏。
(无需手动实现排序或过滤)
您会重新考虑实现自己的排序或过滤功能吗?根据我的经验,它很容易使用。下面的示例使用匿名委托,但您可以轻松定义自己的方法或类来实现复杂的排序或过滤器。这样的类甚至可以具有动态配置和更改排序和过滤器的属性。
使用 List<T>.Sort(Comparison<T> comparison)
与您的自定义比较函数:
// 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)
使用您的自定义过滤器功能:
// 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 命名空间
谢谢 - 我还将Linq考虑到对象,但是我担心的是键入数据模板的灵活性损失,我需要在列表中显示对象。
如果您目前无法预测人们将如何对您的对象集合进行排序和过滤,那么您应该看看 System.Linq.Expressions 命名空间以在运行时按需构建 lambda 表达式(首先让用户构建表达式,然后编译、运行,最后使用反射命名空间枚举结果)。理解它是比较棘手的,但却是无价的功能,可能(对我来说绝对)比 LINQ 本身更具突破性的功能。