WPF的ICollectionView.filter包含大量数据

时间:2009-05-12 07:20:06

标签: c# wpf listview filter

我正在开发一个wpf应用程序,其中包含一个包含大量数据(10 000到100 000)行的列表视图。用户可以将各种过滤器应用于此列表视图,使过滤器逻辑非常先进(并且速度慢)。目前,我的代码的相关部分如下所示:

ICollectionView view = CollectionViewSource.GetDefaultView(hugeList.ItemsSource);
view.Filter = new Predicate<object>(FilterCallback);

private bool FilterCallback(object item)
{
  //Filter logic
}

但是这会在UI线程中运行并在过滤时阻止整个应用程序,从而导致用户体验非常糟糕。所以我的问题是:有没有人知道在wpf中过滤列表视图的“更好”方法,还是应该过滤基础ObservableCollection

2 个答案:

答案 0 :(得分:20)

密切关注您的过滤功能。确保您没有进行任何不必要的装箱/拆箱,并且您没有进行大量计算。你还应该注意你正在使用哪种CollectionView,有些比其他更快。来自Bea's post on sorting

  • 如果您的源实现IEnumerable,则会创建 CollectionView 。如果源实现IEnumerable only ,您将无法对集合进行排序或分组(您只能对其进行过滤)。此外,如果源具有大量项目或执行动态操作(如插入和删除),则perf将不是最佳选择。如果这是您的方案,您应该考虑让您的源实现更强大的接口。 ICollection稍好一些,因为它提供了Count属性。

  • ListCollectionView 是源实现IList时创建的视图类型。与IEnumerable和ICollection相比,IList对大型或动态列表执行得更好,因为它提供了一个索引器,允许我们快速随机访问。此外,IList允许排序,分组和过滤。但理想情况下,您的源集合派生自ObservableCollection,它是数据绑定中所有集合的母亲,因为它提供了一些额外的好处,例如属性和集合更改通知。

  • BindingListCollectionView 是源集合实现IBindingList时由Avalon创建的视图类型。这是我们在ADO.NET场景中处理的视图。它支持排序和分组,但不支持传统的过滤。相反,它有一个额外的CustomFilter属性,可以将过滤委托给DataView(有关详细信息,请参阅我在ADO.NET上的帖子)。

你可以像@mihi所说的那样将过滤踢到另一个线程但是我已经使用CollectionViews在一个ObservableCollection上同时运行多个过滤器,在一个对象上有50,000个项目,有~60个变量(数据库表中的列),没有明显的延迟。

我在过滤器函数中立即注意到的一件事是输入是Object类型,这可能意味着您正在函数内进行类型转换,可能不需要。您还使用不包含返回类型的Predicate,因此可能需要在CollectionView的过滤方法中进行某些类型转换或反射,并且可能会降低您的速度。

答案 1 :(得分:3)

您是否考虑过在另一个线程中过滤或使用调度程序?

WPF Threads: Build more responsive apps with the dispatcher为您提供了一些可用的线程选项概述。