Blog garden client (Universal App) Development essay, universalapp

Source: Internet
Author: User

Blog garden client (Universal App) Development essay, universalapp

In our application (blog Park UAP), the function of pulling more content on the ListView is added (the GridView can also be used). This function is implemented through the ISupportIncrementalLoading interface, this is an interface provided since Windows 8 (of course you can use ScrollViewer to implement this function, but it is a little troublesome and you need to encapsulate it yourself ..).

The interface definition is very simple:

public interface ISupportIncrementalLoading    {        bool HasMoreItems { get; }        IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count);    }

LoadMoreItemsAsync is automatically called by ListView (when IncrementalLoadingTrigger = IncrementalLoadingTrigger. edge), the count parameter indicates how many items are retrieved each time. This parameter is set by ListView. dataFetchSize and ListView. determined by IncrementalLoadingThreshold, HasMoreItems is used to tell ListView whether more projects can be loaded. If it is False, even if the ListView has been rolled to the end, LoadMoreIemsAsync will no longer be triggered.

 

PS: when using ISupportIncrementalLoading, you will find that LoadMoreItemsAsync has been called twice in a row, and the first call always count = 1, this is because ListView needs to use the first project to determine the number of virtualization projects (for more information about virtualization, see MSDN, simply put, the effect is that even if your ListView/GridView displays tens of thousands of projects, the memory will not pop up ). This is no problem for the sample on MSDN, because the data is coming out quickly, but in applications that require Internet connection, you will find that there is only one project at the beginning, after a while, dozens of others came out again. Although there is a reason for doing so, it seems a bit strange, so we ignored the count parameter in the implementation, a fixed number of projects are loaded each time.

Implementation

On MSDN, a simple and general implementation method is provided. This sample stores data by implementing IList, and then implements INotifyCollectionChanged to notify the project of changes.

Public abstract class IncrementalLoadingBase: IList, exist, INotifyCollectionChanged {// omitting the implementation of IList // omitting the implementation of INotifyCollectionChanged public bool HasMoreItems {get {return HasMoreItemsOverride ();} public Windows. foundation. IAsyncOperation <LoadMoreItemsResult> LoadMoreItemsAsync (uint count) {if (_ busy) {throw new InvalidOperationException ("Only one operation in flight at a time");} _ busy = true; return AsyncInfo. run (c) => LoadMoreItemsAsync (c, count);} async Task <LoadMoreItemsResult> LoadMoreItemsAsync (CancellationToken c, uint count) {try {var items = await evaluate (c, count, count); var baseIndex = _ storage. count; _ storage. addRange (items); NotifyOfInsertedItems (baseIndex, items. count); return new LoadMoreItemsResult {Count = (uint) items. count };} finally {_ busy = false ;}}}

To simplify the implementation, we inherit ObservableCollection <T> to store projects and notify changes, and add OnLoadMoreStarted and OnLoadMoreCompleted events to facilitate UI update operations (such as progress bars ).

Public abstract class IncrementalLoadingBase <T>: ObservableCollection <T>, callback {public bool HasMoreItems {get {return callback () ;}} public IAsyncOperation <LoadMoreItemsResult> LoadMoreItemsAsync (uint count) {if (_ busy) {throw new InvalidOperationException ("Only one operation in flight at a time") ;}_ busy = true; return AsyncInfo. run (c) => LoadMoreItemsAsy Nc (c, count);} protected async Task <LoadMoreItemsResult> LoadMoreItemsAsync (CancellationToken c, uint count) {try {// load start event if (this. OnLoadMoreStarted! = Null) {this. OnLoadMoreStarted (count);} var items = await LoadMoreItemsOverrideAsync (c, count); AddItems (items); // if (this. OnLoadMoreCompleted! = Null) {this. OnLoadMoreCompleted (items = null? 0: items. Count);} return new LoadMoreItemsResult {Count = items = null? 0: (uint) items. count };} finally {_ busy = false ;}} public delegate void LoadMoreStarted (uint count); public delegate void LoadMoreCompleted (int count); public event LoadMoreStarted OnLoadMoreStarted; public event LoadMoreCompleted OnLoadMoreCompleted; // <summary> // Add a new project. The reason for this is that it is virtual to facilitate special requirements, for example, do not repeat/</summary> protected virtual void AddItems (IList <T> items) {if (items! = Null) {foreach (var item in items) {this. add (item) ;}} protected abstract Task <IList <T> LoadMoreItemsOverrideAsync (CancellationToken c, uint count); protected abstract bool HasMoreItemsOverride (); protected bool _ busy = false ;}

This is a simple incremental base class. You only need to implement the LoadMoreItemsOverrideAsync method in the subclass and bind it to ListView. ItemsSource.

The following figure shows the effect. (pay attention to the number changes in the upper-right corner of the homepage and the scroll bar in the lower right corner ):

Do you like MVVM? Then you need to modify it on the basis of this class to separate the data retrieval logic and use it as a collection. Below is a simple implementation.

Public class IncrementalLoadingCollection <T>: ObservableCollection <T>, ISupportIncrementalLoading {// Tuple <IList <T>, bool> is used as the return value. The first item is the new project set, whether there are more or not in the second item. You can also customize the object class Func <uint, Task <Tuple <List <T>, bool> _ dataFetchDelegate = null; public IncrementalLoadingCollection (Func <uint, Task <Tuple <List <T>, bool> dataFetchDelegate) {if (dataFetchDelegate = null) throw new ArgumentNullException ("dataFe TchDelegate "); this. _ dataFetchDelegate = dataFetchDelegate;} public bool HasMoreItems {get; private set;} public IAsyncOperation <LoadMoreItemsResult> LoadMoreItemsAsync (uint count) {if (_ busy) {throw new InvalidOperationException ("Only one operation in flight at a time");} _ busy = true; return AsyncInfo. run (c) => LoadMoreItemsAsync (c, count);} protected async Task <LoadMoreItemsResult> Loa DMoreItemsAsync (CancellationToken c, uint count) {try {if (this. OnLoadMoreStarted! = Null) {this. onLoadMoreStarted (count);} // we ignored CancellationToken, because we do not need to cancel it for now. You can add var result = await this. _ dataFetchDelegate (count); var items = result. item1; if (items! = Null) {foreach (var item in items) {this. add (item) ;}// whether there is more this. hasMoreItems = result. item2; // if (this. onLoadMoreCompleted! = Null) {this. OnLoadMoreCompleted (items = null? 0: items. Count);} return new LoadMoreItemsResult {Count = items = null? 0: (uint) items. count };} finally {_ busy = false ;}} public delegate void LoadMoreStarted (uint count); public delegate void LoadMoreCompleted (int count); public event LoadMoreStarted OnLoadMoreStarted; public event LoadMoreCompleted OnLoadMoreCompleted; protected bool _ busy = false ;}

Now this guy turns into a collection. When creating an instance, pass in the corresponding proxy, and then bind it to ItemsSource in your View.

Var collection = new IncrementalLoadingCollection <string> (count = >{// corresponding get more logic return Task. run () => Tuple. create (new List <string> {"I Am a false data"}, true ));});
Summary

Incremental loading can provide users with a smoother experience when they need to display a large amount of data. By using ISupportIncrementalLoading, we only need to implement the data retrieval logic, we don't need to worry about when to call it. You are welcome to continue your attention.

 

Windows Phone Store App link:

Bytes

 

Windows Store App link:

Http://apps.microsoft.com/windows/zh-cn/app/c76b99a0-9abd-4a4e-86f0-b29bfcc51059

 

GitHub open source link:

Https://github.com/MS-UAP/cnblogs-UAP

 

MSDN Sample Code:

Https://code.msdn.microsoft.com/CNBlogs-Client-Universal-9c9692d1

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.