使用CreateDerivedCollection进行分页

时间:2017-02-13 14:07:36

标签: c# wpf reactiveui

我正在开发一个用于处理WPF列表框中显示的20k +项目的应用程序,因此显然需要将它们分割成页面。

我目前的解决方案有点滞后:

我在所有项目上使用带有Paraller.ForEach的async命令应用过滤器,并设置MatchesFilter属性。这非常有效:

 FilteredItems = _allItems.CreateDerivedCollection(x => x, x
=> x.MatchesFilter, scheduler: RxApp.TaskpoolScheduler);

_count =FilteredSignatures.CountChanged.StartWith(0).ToProperty(this, x => x.Count);

这很快,保持UI响应,你可以在WPF标签中看到Count快速更改。

当过滤结束时,我(在主线程上):

Items.Clear();
foreach (var s in FilteredItems.Skip((CurrentPage - 1) * temsPerPage).Take(ItemsPerPage))
                        Items.Add(s);

这就是我的问题所在。每个项目与图像一起显示,该图像从URL加载异步。 Clear()部分以明显的方式冻结了UI。我每页有250个项目(它应该不会少,因为用户应该能够用他的眼睛根据图像搜索项目。)

有没有更好的方法呢?我知道DynamicData,但使用RxUI 6.x.

2 个答案:

答案 0 :(得分:2)

您可以将DynamicData与RxUI 7.0一起使用

答案 1 :(得分:0)

动态数据4适用于RxUI 6.5,它是我一般使用的。话虽如此,我想发布一个使用RxUI来实现它的方法的代码示例。主要是因为您不需要清除然后重新添加以更新DerivedList。

[TestMethod]
    [TestCategory("Reactive")]
    public async Task PagingReactiveUITest()
    {

        ReactiveList<int> SourceList = new ReactiveList<int>();
        for (int i = 0; i < 100; i++)
        {
            SourceList.Add(i);
        }

        Tuple<int, int> pageWindow = new Tuple<int, int>(0, 10);


        //ReactiveComamnd that triggers paging
        ReactiveCommand<Unit> updatePaging =
            ReactiveCommand.CreateAsyncObservable<Unit>((_) =>
            {

                pageWindow = new Tuple<int, int>(10, 20);
                return Observable.Return(Unit.Default);
            });


        var PagedList =
            SourceList
            .CreateDerivedCollection(
                x => x,
                filter: (item) => item >= pageWindow.Item1 && item < pageWindow.Item2,
                signalReset: updatePaging);



        Assert.AreEqual(PagedList.First(), 0);
        Assert.AreEqual(PagedList.Last(), 9);

        //Trigger Paging
        await updatePaging.ExecuteAsync(null);

        Assert.AreEqual(PagedList.First(), 10);
        Assert.AreEqual(PagedList.Last(), 19);
    }

另一个注意事项..如果您计划对列表进行大量更改,您还可以执行以下操作:

using (SourceList.SuppressChangeNotifications())
{ 
      //DO STUFF
}

这会阻止消息进入用户界面,直到你搞清楚列表