【问题标题】:Sorting and Filtering a collection in a Paged ListBox在分页列表框中对集合进行排序和过滤
【发布时间】:2015-04-16 20:01:28
【问题描述】:

我有一个包含 10,000 个项目的数据库,您可以在应用运行时向其中添加和删除。

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

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

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

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

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

然后通过解析MainOC,我们将调用FilteredList,为所有匹配过滤器的项目创建一个List

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

缺点:

  • 每次应用排序操作时,您都必须重新创建 ListCollectionView
  • 您必须在每次页面时重新创建 ListCollectionView
  • 每次更改过滤器时,您都必须重新创建 ListCollectionView
  • 每次向MainOC 添加或删除项目时,您都必须重新创建ListCollectionView

有没有更好的方法我错过了?

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

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

寻找您可以提供的任何输入!

【问题讨论】:

    标签: wpf listcollectionview


    【解决方案1】:

    这是一个使用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<>);
    

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

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

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

    有关动态数据的更多信息,请参阅

    Dynamic data on Github

    Wpf demo app

    【讨论】:

    • 从 nuget 安装 Rx-Xaml 并包含命名空间 System.Reactive.Linq
    • 试图设置一个超级简单的例子。 gist.github.com/julesx/acd0e1c03f9d90bd6094。当我添加到缓存时什么都没有显示,只有当我直接添加到 OC 时。我错过了一些基本的东西吗?
    • 我周末去看看。现在看不到办公室代理块的要点!
    • @RolandPheasant 感谢您的工作。我已在 WPF Room 中为您的图书馆添加了书签
    • PageController、FilterController 和 SortController 过时了吗?我在当前 NuGet 包 DynamicData 6.1.4 中找不到它们
    猜你喜欢
    • 2015-09-18
    • 2013-05-11
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多