從新想象 Windows 8 Store Apps (54) - 綁定: 增量方式加載數據

[源碼下載]


html

從新想象 Windows 8 Store Apps (54) - 綁定: 增量方式加載數據



做者:webabcd


介紹
從新想象 Windows 8 Store Apps 之 綁定html5

  • 經過實現 ISupportIncrementalLoading 接口,爲 ListViewBase 的增量加載提供數據



示例
實現 ISupportIncrementalLoading 接口,以便爲 ListViewBase 的增量加載提供數據
Binding/MyIncrementalLoading.csweb

/*
 * 演示如何實現 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.xamlexpress

<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.cswindows

/*
 * 演示如何實現 ListViewBase 的增量加載
 * 數據源須要實現 ISupportIncrementalLoading 接口,詳見:MyIncrementalLoading.cs
 * 
 * 
 * ListViewBase - ListView 和 GridView 均繼承自 ListViewBase
 *     IncrementalLoadingTrigger - 增量加載的觸發方式(IncrementalLoadingTrigger 枚舉)
 *         Edge - 容許觸發增量加載,默認值
 *         None - 禁止觸發增量加載
 *     DataFetchSize - 預提數據的大小,默認值 3.0
 *         本例將此值設置爲 4.0 ,其效果爲(注:本例中的 ListView 每頁可顯示的數據量爲 6 條或 7 條,如下計算需基於此)
 *         一、先獲取 1 條數據,爲的是儘可能快地顯示數據
 *         二、再獲取 4.0 * 1 條數據
 *         三、再獲取 4.0 * (6 或 7,若是 ListView 當前顯示了 6 條數據則爲 6,若是 ListView 當前顯示了 7 條數據則爲 7) 條數據
 *         四、之後每次到達閾值後,均增量加載 4.0 * (6 或 7,若是 ListView 當前顯示了 6 條數據則爲 6,若是 ListView 當前顯示了 7 條數據則爲 7) 條數據
 *     IncrementalLoadingThreshold - 閾值,默認值 0.0
 *         本例將此值設置爲 2.0 ,其效果爲(注:本例中的 ListView 每頁可顯示的數據量爲 6 條或 7 條)
 *         一、滾動中,若是已準備好的數據少於 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
[源碼下載]app

相關文章
相關標籤/搜索