介紹
重新想象 Windows 8 Store Apps 之 綁定
通過實現 ISupportIncrementalLoading 接口,為 ListViewBase 的增量加載提供數據
示例
實現 ISupportIncrementalLoading 接口,以便為 ListViewBase 的增量加載提供數據
Binding/MyIncrementalLoading.cs
/*
* 演示如何實現 ISupportIncrementalLoading 接口,以便為 ListViewBase 的增量加載提
供數據
*
* ISupportIncrementalLoading - 用於支持增量加載
* HasMoreItems - 是否還有更多的數據
* IAsyncOperation<LoadMoreItemsResult> 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<T> : ObservableCollection<T>,
ISupportIncrementalLoading
{
// 是否正在異步加載中
private bool _isBusy = false;
// 提供數據的 Func
// 第一個參數:增量加載的起始索引;第二個參數:需要獲取的數據量;第三個參數:獲取到的數據集合
private Func<int, int, List<T>> _funcGetData;
// 最大可顯示的數據量
private uint _totalCount = 0;
/// <summary>
/// 構造函數
/// </summary>
/// <param name="totalCount">最大可顯示的數據量</param>
/// <param name="getDataFunc">提供數據的 Func</param>
public MyIncrementalLoading(uint totalCount, Func<int, int, List<T>> getDataFunc)
{
_funcGetData = getDataFunc;
_totalCount = totalCount;
}
/// <summary>
/// 是否還有更多的數據
/// </summary>
public bool HasMoreItems
{
get { return this.Count < _totalCount; }
}
/// <summary>
/// 異步加載數據(增量加載)
/// </summary>
/// <param name="count">需要加載的數據量</param>
/// <returns></returns>
public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint
count)
{
if (_isBusy)
{
throw new InvalidOperationException("忙著呢,先不搭理你");
}
_isBusy = true;
var dispatcher = Window.Current.Dispatcher;
return AsyncInfo.Run(
(token) =>
Task.Run<LoadMoreItemsResult>(
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
<Page
x:Class="XamlDemo.Binding.IncrementalLoading"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Binding"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Transparent">
<Grid Margin="120 0 0 10">
<TextBlock Name="lblMsg" FontSize="14.667" />
<ListView x:Name="listView" Width="300" Height="300" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0 30 0 0">
<ListView.ItemTemplate>
<DataTemplate>
<Border Background="Blue" Width="200" CornerRadius="3"
HorizontalAlignment="Left">
<TextBlock Text="{Binding Name}" FontSize="14.667"
/>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<TextBlock Name="lblLog" FontSize="14.667" Margin="0 350 0 0"
/>
</Grid>
</Grid>
</Page>
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<Employee> _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<Employee>(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
[源碼下載]:http://files.cnblogs.com/webabcd/Windows8.rar
查看本欄目