Blog Park Client (Universal App) Development essay--Incremental load (incremental loading)

Source: Internet
Author: User

In our app (blog Park UAP), added a ListView pull-up to get more content (the GridView can also), this feature is implemented through the Isupportincrementalloading interface, which is a Windows 8 Start with the interface (of course you can do this through the ScrollViewer, just a little bit of trouble, but also to encapsulate themselves. )。

The definition of this interface is simple:

 Public Interface isupportincrementalloading    {        boolget;}        Iasyncoperation<LoadMoreItemsResult> loadmoreitemsasync (uint  count);    }

Loadmoreitemsasync is automatically called by the ListView (When Incrementalloadingtrigger = Incrementalloadingtrigger.edge), the Count parameter indicates how many items to fetch each time , this parameter is determined by Listview.datafetchsize and Listview.incrementalloadingthreshold, Hasmoreitems is used to tell the ListView if there are more items to load, False if Listv Iew has rolled to the end and will no longer trigger loadmoreiemsasync.

PS: In the process of using isupportincrementalloading, you will find that Loadmoreitemsasync is continuously called 2 times, and the first call is always count= 1, this is because the ListView needs to use the first project to determine the number of virtualized projects (there is a bit more about virtualization, please refer to MSDN, simply say that the effect is your listview/gridview even if you want to show tens of thousands of items, the memory will not explode). This is not a problem for sample on MSDN, because the data comes out quickly, but in applications that need to be networked you will find that there is only one project, and in a moment the other dozens of comes out again, although it is justified, but it looks a little weird, So we ignored the count parameter in the implementation and loaded a fixed number of items each time.

Realize

A simple, generic implementation is provided on MSDN, which stores data by implementing IList and then implements INotifyCollectionChanged to inform the project of changes.

 Public Abstract classincrementalloadingbase:ilist, isupportincrementalloading, inotifycollectionchanged {//omitting the implementation of IList//implementation of omitting inotifycollectionchanged         Public BOOLHasmoreitems {Get{returnhasmoreitemsoverride ();} }           PublicWindows.foundation.iasyncoperation<loadmoreitemsresult> Loadmoreitemsasync (UINTcount) {             if(_busy) {Throw NewInvalidOperationException ("Only one operation in flight at a time"); } _busy=true; returnAsyncinfo.run ((c) =Loadmoreitemsasync (c, Count)); }         AsyncTask<loadmoreitemsresult> Loadmoreitemsasync (CancellationToken C,UINTcount) {             Try             {                 varItems =awaitLoadmoreitemsoverrideasync (c, Count); varBaseIndex =_storage.                  Count; _storage.                  AddRange (items); Notifyofinserteditems (BaseIndex, items.                  Count); return NewLoadmoreitemsresult {Count = (UINT) items.             Count}; }             finally{_busy=false; }         } }

To simplify the implementation, we have inherited the observablecollection<t> to achieve the purpose of storing items, notifying changes, and adding onloadmorestarted and onloadmorecompleted events, facilitates updating the UI (such as a progress bar).

 Public Abstract classIncrementalloadingbase<t>: observablecollection<t>, isupportincrementalloading { Public BOOLHasmoreitems {Get{returnhasmoreitemsoverride ();} }         PublicIasyncoperation<loadmoreitemsresult> Loadmoreitemsasync (UINTcount) {            if(_busy) {Throw NewInvalidOperationException ("Only one operation in flight at a time"); } _busy=true; returnAsyncinfo.run ((c) =Loadmoreitemsasync (c, Count)); }        protected AsyncTask<loadmoreitemsresult> Loadmoreitemsasync (CancellationToken C,UINTcount) {            Try            {                //Load Start Event                if( This. Onloadmorestarted! =NULL)                {                     This.                Onloadmorestarted (count); }                varItems =awaitLoadmoreitemsoverrideasync (c, Count);                Additems (items); //Load Complete Event                if( This. Onloadmorecompleted! =NULL)                {                     This. onloadmorecompleted (items = =NULL?0: Items.                Count); }                return NewLoadmoreitemsresult {Count = items = =NULL?0: (UINT) items.            Count}; }            finally{_busy=false; }        }         Public Delegate voidLoadmorestarted (UINTcount);  Public Delegate voidLoadmorecompleted (intcount);  Public Eventloadmorestarted onloadmorestarted;  Public Eventloadmorecompleted onloadmorecompleted; /// <summary>        ///Add new items, the reason is virtual is to facilitate special requirements, such as non-repetition/// </summary>        protected Virtual voidAdditems (ilist<t>items) {            if(Items! =NULL)            {                foreach(varIteminchitems) {                     This.                ADD (item); }            }        }        protected AbstractTask<ilist<t>> Loadmoreitemsoverrideasync (CancellationToken C,UINTcount); protected Abstract BOOLhasmoreitemsoverride (); protected BOOL_busy =false; }

Such a simple incremental load base class would have to implement the Loadmoreitemsoverrideasync method in the subclass, and bind to the Listview.itemssource.

Use the following two images (note the number changes in the top right corner of the home page and the scroll bar at the bottom right):

Do you like MVVM? Then you need to modify it on the basis of this class, separating the logic from the data and using it as a collection, and here is a simple implementation.

 Public classIncrementalloadingcollection<t>: observablecollection<t>, isupportincrementalloading{//here in order to simply use the tuple<ilist<t>, bool> as the return value, the first item is the new item collection, whether the second item has more, or you can customize the entity classfunc<UINT, Task<tuple<list<t>,BOOL>>> _datafetchdelegate =NULL;  PublicIncrementalloadingcollection (func<UINT, Task<tuple<list<t>,BOOL>>>datafetchdelegate) {        if(Datafetchdelegate = =NULL)Throw NewArgumentNullException ("datafetchdelegate");  This. _datafetchdelegate =datafetchdelegate; }     Public BOOLHasmoreitems {Get; Private Set; }     PublicIasyncoperation<loadmoreitemsresult> Loadmoreitemsasync (UINTcount) {        if(_busy) {Throw NewInvalidOperationException ("Only one operation in flight at a time"); } _busy=true; returnAsyncinfo.run ((c) =Loadmoreitemsasync (c, Count)); }    protected AsyncTask<loadmoreitemsresult> Loadmoreitemsasync (CancellationToken C,UINTcount) {        Try        {            if( This. Onloadmorestarted! =NULL)            {                 This.            Onloadmorestarted (count); }            //We ignore the cancellationtoken, because we do not need to cancel at the moment, we need to add            varresult =await  This. _datafetchdelegate (count); varItems =result.            Item1; if(Items! =NULL)            {                foreach(varIteminchitems) {                     This.                ADD (item); }            }            //do you have more             This. Hasmoreitems =result.            ITEM2; //Load Complete Event            if( This. Onloadmorecompleted! =NULL)            {                 This. onloadmorecompleted (items = =NULL?0: Items.            Count); }            return NewLoadmoreitemsresult {Count = items = =NULL?0: (UINT) items.        Count}; }        finally{_busy=false; }    }     Public Delegate voidLoadmorestarted (UINTcount);  Public Delegate voidLoadmorecompleted (intcount);  Public Eventloadmorestarted onloadmorestarted;  Public Eventloadmorecompleted onloadmorecompleted; protected BOOL_busy =false;}

Now this guy becomes a collection, when you create an instance, pass in the corresponding proxy, and then bind it to the ItemsSource in your view.

var New incrementalloadingcollection<String> (count + =            {                //  corresponding get more logic                 return task.run (() = Tuple.create (new list<string ) I am false data "true");            });
Summary

Incremental loading can give users a smoother experience when they need to display large amounts of data, and by using isupportincrementalloading, we only need to implement the logic to fetch the data, and when the call does not need our attention. We welcome your continued attention.

Windows Phone Store App Link:

http://www.windowsphone.com/zh-cn/store/app/Blog Park-UAP/500F08F0-5BE8-4723-AFF9-A397BEEE52FC

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

Blog Park Client (Universal App) Development essay--Incremental load (incremental loading)

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.