我正在开发一个用于处理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.
答案 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
}
这会阻止消息进入用户界面,直到你搞清楚列表