[源码下载]
重新想象 Windows 8 Store Apps (54) - 绑定: 增量方式加载数据
作者:webabcd
介绍
重新想象 Windows 8 Store Apps 之 绑定
- 通过实现 ISupportIncrementalLoading 接口,为 ListViewBase 的增量加载提供数据
示例
实现 ISupportIncrementalLoading 接口,以便为 ListViewBase 的增量加载提供数据
Binding/MyIncrementalLoading.cs
/*
* 演示如何实现 ISupportIncrementalLoading 接口,以便为 ListViewBase 的增量加载提供数据
*
* ISupportIncrementalLoading - 用于支持增量加载
* HasMoreItems - 是否还有更多的数据
* IAsyncOperation LoadMoreItemsAsync(uint count) - 异步加载指定数量的数据(增量加载)
*
* LoadMoreItemsResult - 增量加载的结果
* Count - 实际已加载的数据量
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
namespace XamlDemo.Binding
{
public class MyIncrementalLoading : ObservableCollection, ISupportIncrementalLoading
{
// 是否正在异步加载中
private bool _isBusy = false;
// 提供数据的 Func
// 第一个参数:增量加载的起始索引;第二个参数:需要获取的数据量;第三个参数:获取到的数据集合
private Func _funcGetData;
// 最大可显示的数据量
private uint _totalCount = 0;
///
/// 构造函数
///
/// 最大可显示的数据量
/// 提供数据的 Func
public MyIncrementalLoading(uint totalCount, Func getDataFunc)
{
_funcGetData = getDataFunc;
_totalCount = totalCount;
}
///
/// 是否还有更多的数据
///
public bool HasMoreItems
{
get { return this.Count < _totalCount; }
}
///
/// 异步加载数据(增量加载)
///
/// 需要加载的数据量
///
public IAsyncOperation LoadMoreItemsAsync(uint count)
{
if (_isBusy)
{
throw new InvalidOperationException("忙着呢,先不搭理你");
}
_isBusy = true;
var dispatcher = Window.Current.Dispatcher;
return AsyncInfo.Run(
(token) =>
Task.Run(
async () =>
{
try
{
// 模拟长时任务
await Task.Delay(1000);
// 增量加载的起始索引
var startIndex = this.Count;
await dispatcher.RunAsync(
CoreDispatcherPriority.Normal,
() =>
{
// 通过 Func 获取增量数据
var items = _funcGetData(startIndex, (int)count);
foreach (var item in items)
{
this.Add(item);
}
});
// Count - 实际已加载的数据量
return new LoadMoreItemsResult { Count = (uint)this.Count };
}
finally
{
_isBusy = false;
}
},
token));
}
}
}
演示如何实现 ListViewBase 的增量加载
Binding/IncrementalLoading.xaml
Binding/IncrementalLoading.xaml.cs
/*
* 演示如何实现 ListViewBase 的增量加载
* 数据源需要实现 ISupportIncrementalLoading 接口,详见:MyIncrementalLoading.cs
*
*
* ListViewBase - ListView 和 GridView 均继承自 ListViewBase
* IncrementalLoadingTrigger - 增量加载的触发方式(IncrementalLoadingTrigger 枚举)
* Edge - 允许触发增量加载,默认值
* None - 禁止触发增量加载
* DataFetchSize - 预提数据的大小,默认值 3.0
* 本例将此值设置为 4.0 ,其效果为(注:本例中的 ListView 每页可显示的数据量为 6 条或 7 条,以下计算需基于此)
* 1、先获取 1 条数据,为的是尽量快地显示数据
* 2、再获取 4.0 * 1 条数据
* 3、再获取 4.0 * (6 或 7,如果 ListView 当前显示了 6 条数据则为 6,如果 ListView 当前显示了 7 条数据则为 7) 条数据
* 4、以后每次到达阈值后,均增量加载 4.0 * (6 或 7,如果 ListView 当前显示了 6 条数据则为 6,如果 ListView 当前显示了 7 条数据则为 7) 条数据
* IncrementalLoadingThreshold - 阈值,默认值 0.0
* 本例将此值设置为 2.0 ,其效果为(注:本例中的 ListView 每页可显示的数据量为 6 条或 7 条)
* 1、滚动中,如果已准备好的数据少于 2.0 * (6 或 7,如果 ListView 当前显示了 6 条数据则为 6,如果 ListView 当前显示了 7 条数据则为 7) 条数据,则开始增量加载
*/
using Windows.UI.Xaml.Controls;
using XamlDemo.Model;
using System.Linq;
using System.Collections.Specialized;
using System;
namespace XamlDemo.Binding
{
public sealed partial class IncrementalLoading : Page
{
// 实现了增量加载的数据源
private MyIncrementalLoading _employees;
public IncrementalLoading()
{
this.InitializeComponent();
this.Loaded += IncrementalLoading_Loaded;
}
void IncrementalLoading_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
listView.IncrementalLoadingTrigger = IncrementalLoadingTrigger.Edge;
listView.DataFetchSize = 4.0;
listView.IncrementalLoadingThreshold = 2.0;
_employees = new MyIncrementalLoading(1000, (startIndex, count) =>
{
lblLog.Text += string.Format("从索引 {0} 处开始获取 {1} 条数据", startIndex, count);
lblLog.Text += Environment.NewLine;
return TestData.GetEmployees().Skip(startIndex).Take(count).ToList();
});
_employees.CollectionChanged += _employees_CollectionChanged;
listView.ItemsSource = _employees;
}
void _employees_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
lblMsg.Text = "已获取的数据量:" + _employees.Count.ToString();
}
}
}
OK
[源码下载] |