带有大量数据的 WPF 的 ICollectionView.filter [英] WPF's ICollectionView.filter with large sets of data

查看:25
本文介绍了带有大量数据的 WPF 的 ICollectionView.filter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm working on an wpf app which contains a listview with quite a lot of data (10 000 to 100 000) rows. The user can apply all sorts of filters to this listview making the filter logic quite advanced (and slow). For now, the relevant part of my code looks like this:

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

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

但这会在 UI 线程中运行并在过滤时阻塞整个应用程序,这会导致非常差的用户体验.所以我对你们所有人的问题是:有没有人知道在 wpf 中过滤列表视图的更好"方法,还是我应该过滤底层的 ObservableCollection ?

But this runs in the UI thread and blocks the entire application when filtering which gives a very poor user experience. So my question to you all is: does anyone know a 'better' way to filter a listview in wpf or should I filter the underlying ObservableCollection instead?

推荐答案

密切注意您的过滤器功能.确保您没有进行任何不必要的装箱/拆箱,并且没有在其中进行大量计算.您还应该注意您使用的是哪种 CollectionView,有些比其他的更快.来自 Bea 关于排序的帖子:

Pay close attention to your filter function. Make sure you aren't doing any unnecessary boxing/unboxing and you aren't doing extensive calculations in it. You should also pay attention to which kind of CollectionView you're using, some are faster than others. From Bea's post on sorting:

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

  • A CollectionView is created if your source implements IEnumerable. If the source implements IEnumerable only, you will not be able to sort or group the collection (you can only filter it). Also, perf will not be the best if the source has a large number of items or if you perform dynamic operations such as insertions and deletions. If this is your scenario, you should consider having your source implement a stronger interface. ICollection is slightly better because it provides a Count property.

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

ListCollectionView is the view type created when the source implements IList. Compared to IEnumerable and ICollection, IList performs much better for large or dynamic lists because it provides an indexer, allowing us quick random access. In addition, IList allows sorting, grouping and filtering. But ideally your source collection derives from ObservableCollection, the mother of all collections in the eyes of data binding, since it provides several extra goodies such as property and collection change notifications.

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

BindingListCollectionView is the type of view created by Avalon when the source collection implements IBindingList. This is the view we deal with in the ADO.NET scenario. It supports sorting and grouping, but not traditional filtering. Instead, it has an additional CustomFilter property that delegates filtering to the DataView (see my post on ADO.NET for more details).

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

You can kick the filtering to a different thread as @mihi said but I have used CollectionViews to run multiple filters concurrently on an ObservableCollection with 50,000 items on an object with ~60 variables (columns in a database table) without noticeable lag.

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

One thing I notice immediately in your filter function is the input is of type Object which likely means you're doing a type conversion within the function and may not need to. You also use Predicate which doesn't include a return type so that probably requires some type conversions or reflection within the CollectionView's filtering methods and might slow you down as well.

这篇关于带有大量数据的 WPF 的 ICollectionView.filter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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