【Win10 应用开发】实现数据的增量加载
今天,老周有小故事讲,国庆期间。有一次老周在某站台上候公交车。老周旁边也站满了人,突然,有一位头发弄得像电线杆的小伙子,不知为何,没有先兆地就大笑起来。
老周先是看了那小伙子一眼,他手上没有拿什么东西(一瓶水),也没在看书或手机,就这样忽然大笑不止。随即,老周便后退了两步,观察一下其他人有什么反应。
一位年轻妈妈拉着小女儿走开了,接着,一位大叔走到垃圾桶旁边拨弄烟灰;然后,一位女孩后退了一两步;站在发笑者旁边的一位先生蹲下身来,不知道在做什么……
如果是你,你会有什么反应?
====================================================
好了,“恐怖”故事讲完了,下面进入正题。
本次老周就和大伙儿说说有关增量加载的实现方法,其实叫做“预提取”感觉也可行。当列表控件要绑定一个非常大的列表时,如果一次性加载所有数据,估计是很费时间的,特别是当数据是从网络上提取的情况下。
在这种情形下,是相当有必要考虑使用增量加载方案,我也不知道什么叫增量加载,就是按照Incremental Load直接翻译过来的,至于合适不合适,见仁见智吧。重要的是,我们知道它是个什么东东就行,管它叫什么。
支持增量加载的控件必须是ListViewBase类的派生类。ListViewBase类公开一个LoadMoreItemsAsync方法,调用它可以执行预提取操作。正常情况下,不需要我们去调用它,当列表控件的滚动条滚动到边沿时,会自动触发预提取操作。
但是,如果你把IncrementalLoadingTrigger属性设置为IncrementalLoadingTrigger.None的话,就需要手动触发增量加载了,一般来说没必要这么干,它控件自己完成就好了。
支持增量加载的集合必须实现ISupportIncrementalLoading接口,这个接口只有两个成员:
1、只读属性HasMoreItems,如果还有要增量加载的项,就返回true,如果没有项要加载了,就返回false。
2、LoadMoreItemsAsync方法。当增量加载操作被激活后这个方法会被调用,我们需要实现这个方法来提取数据。方法原型如下:
IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(System.UInt32 count);
由于该方法返回的是IAsyncOperation<TResult>,即专用于Windows运行时的异步操作,因为实现接口的类型没有直接公开(大概是以COM形式注册),不能在代码中直接实例化,所以要借助System.Runtime.InteropServices.WindowsRuntime命名空间下的AsyncInfo静态类来完成。把基于.net的异步方法(返回Task或Task<TResult>)转换为Windows运行时的异步操作方法。方法参数count表示此次加载操作要提取的数据条数。
我们还要考虑这么个问题:增量加载修改了源集合后,UI上显示的列表也应该同步更新,故集合除了要实现ISupportIncrementalLoading接口外,还应该实现INotifyCollectionChanged接口。
如果我们自定义集合类来实现这两个接口,也不是不可,不过有更简单的方法。ObservableCollection<T>类身就已经实现了INotifyCollectionChanged接口,所以,我们直接从ObservableCollection<T>类派生,同时实现ISupportIncrementalLoading接口,这样一来,可以省去不少功夫,何乐而不为?
知道了原理,按照老周的惯用手段,就应该上示例了。
咱们先写一个万能抽象类,并且为泛型类,带类型参数T,这样,你希望增量加载哪些类型的数据,就直接从该抽象类派生自己的类就可以了,你也可以根据实际情况来完善扩充。
public abstract class LoadMoreBase<T> : ObservableCollection<T>, ISupportIncrementalLoading { /// <summary> /// 此属性表示是否还有可加载的项。 /// </summary> public bool HasMoreItems { get { return HasMoreItemsCore; } } /// <summary> /// 该属性可在派生类中重写。 /// </summary> protected abstract bool HasMoreItemsCore { get; } public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count) { return AsyncInfo.Run(c => LoadMoreItemsAsyncCore(c, count)); } /// <summary> /// 该方法可在派生类中重写。 /// </summary> protected abstract Task<LoadMoreItemsResult> LoadMoreItemsAsyncCore(CancellationToken cancel, uint count); }
温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/66723.html
- 上一篇:C# 内存管理优化畅想(二)
- 下一篇:20151009 C# 第一篇 程序编写规范