[W8] Scroll infiinito ( I )

 

Una de las mayores bazas de una interfaz de usuario es cómo se muestran los elementos y cómo se van cargando. En el caso de Windows 8 (y Windows Phone) disponer de elementos en un ListView es algo común. Pero cuando llegamos al final de la lista, podemos adoptar dos alternativas:

  • Colocar un botón tipo “Cargar más elementos”
  • O hacer que automáticamente cargue los elementos según lo necesite. Evidentemente, este es el caso que vamos a comentar.

En primer lugar tenemos un ListView con un ItemSource asociado a un ObservableCollection<T>. Para detectar si hay más elementos, el ListView dispone de una propiedad llamada IncrementalLoadingTrigger. Esta propiedad por defecto está ajustada a Edge. Si queremos que no haya ningún tipo de carga incremental, hay que ajustarla a None.

En segundo lugar, tenemos que lograr que los datos nos indiquen cuándo es necesario obtener más elementos. Como hasta ahora usamos un ObservableCollection<T> como binding, necesitamos cambiarlo un poco. En este punto se introduce la interfaz ISupportIncrementalLoading, que se encargará de notificar al destino del binding si hay más elementos disponibles para cargar y un método para cargar los datos en función de la cantidad de elementos previamente cargados:

HasMoreItems: Indica si hay más elementos para cargar.

LoadMoreItemsAsync: Carga asíncrona de los nuevos elementos.

Partiendo de lo anterior, necesitamos crear un nuevo tipo que implemente la interfaz ISupportIncrementalLoading y la ObservableCollection<T> para poder bindear los datos. Veamos un ejemplo que yo he llamado IncrementalSource:

Code Snippet
  1. public class IncrementalSource<T> : ObservableCollection<T>, ISupportIncrementalLoading
  2.         {
  3.             private int VirtualCount { get; set; }
  4.  
  5.             public IncrementalSource()
  6.             {
  7.  
  8.             }
  9.  
  10.             #region ISupportIncrementalLoading
  11.  
  12.             public bool HasMoreItems
  13.             {
  14.                 get { return this.VirtualCount > 0; }
  15.             }
  16.  
  17.             public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
  18.             {
  19.  
  20.             }
  21.             #endregion
  22.         }

Sólo tenemos que rellenar el método de LoadMoreItemAsync., que devuelve un IAsyncOperation de LoadMoreResultItems. Esta estructura tiene un único campo Count que indica la cantidad de elementos que han sido cargados. De este modo se va notificando al destino del binding qué elementos se van cargando de forma asíncrona para que los vaya obteniendo y renderizando. Voy a adjuntar un ejemplo teórico de cómo se podría rellenar ese método:

Code Snippet
  1. public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
  2.         {
  3.             return Task.Run<LoadMoreItemsResult>(
  4.                 async () =>
  5.                 {
  6.                     var result = await SourceManager.Load(count);
  7.                     foreach(var items in result)
  8.                     {
  9.                         this.Add(result);     
  10.                     }
  11.                     return new LoadMoreItemsResult() { Count = (uint)result.Count };
  12.                 }).AsAsyncOperation<LoadMoreItemsResult>();
  13.         }

Y si el ListView está dentro de un ScrollViewer, ya tendremos el scroll infinito funcionando.

Un comentario en “[W8] Scroll infiinito ( I )”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *