在分页列表框中对集合进行排序和过滤

Sorting and Filtering a collection in a Paged ListBox

我有一个包含 10,000 个项目的数据库,您可以在应用 运行.

时添加和删除这些项目

我有一个ListBox,最多显示100个项目,支持分页。

您可以对这 10,000 个项目进行筛选和排序,这需要立即反映在列表框中。

我有一个按钮,只要它通过过滤器就可以随机选择一个项目。

用于此类操作的最佳 collections/views 集合是什么?

到目前为止,我的第一步是在数据库中创建一个包含所有项目的 ObservableCollection,我们称之为 MainOC

然后通过解析 MainOC 创建与过滤器匹配的所有项目的 List,我们将其称为 FilteredList.

然后根据上面的 List 创建一个 ListCollectionView 来保存前 100 个项目。

缺点:

有没有我遗漏的更好的方法?

例如,我看到您可以将过滤器应用于 ListCollectionView。我应该用所有 10,000 件物品填充我的 ListCollectionView 吗?但是我怎样才能限制我的 ListBox 显示的项目数量呢?

我应该直接对数据库进行过滤和排序吗?我可以直接从数据库构建 FilteredList 并基于它创建我的 ListCollectionView,但这仍然具有上面列出的所有缺点。

正在寻找您可以提供的任何意见!

这个问题很容易用 DynamicData 解决。动态数据是基于 rx 所以如果你不熟悉美妙的 Rx 我建议你开始学习它。有相当多的学习曲线,但回报是巨大的。

不管怎样回到我的回答,动态数据的出发点是将一些数据放入缓存中,缓存是用如下键构造的

var myCache = new SourceCache<MyObject, MyId>(myobject=>myobject.Id)

显然作为缓存有添加、更新和删除的方法,所以我不会在这里展示这些。

动态数据提供大量扩展和一些控制器来动态查询数据。对于分页我们需要一些元素来解决这个问题

//this is an extension of observable collection optimised for dynamic data
var collection = new ObservableCollectionExtended<MyObject>();
//these controllers enable dynamically changing filter, sort and page
var pageController = new PageController();  
var filterController = new FilterController<T>(); 
var sortController = new SortController<T>(); 

使用这些控制器创建数据流并将结果绑定到集合中。

var mySubscription = myCache.Connect()
    .Filter(filterController)
    .Sort(sortController)
    .Page(pageController)
    .ObserveOnDispatcher() //ensure we are on the UI thread
    .Bind(collection)
    .Subscribe() //nothing happens until we subscribe.  

您可以随时更改控制器的参数来过滤、排序、分页和绑定数据,如下所示

//to change page
pageController.Change(new PageRequest(1,100));
//to change filter 
filterController.Change(myobject=> //return a predicate);
//to change sort
sortController .Change( //return an IComparable<>);

当任何控制器参数发生变化或任何数据发生变化时,可观察集合将像变魔术一样自我维护。

您现在唯一需要考虑的是将数据库数据加载到缓存中所需的代码。

在不久的将来,我将创建一个此功能的工作示例。

有关动态数据的详细信息,请参阅

Dynamic data on Github

Wpf demo app