Actualizar los elementos GridView y ListView de forma incremental (XAML)

Cuando un control ListView o GridView tiene muchos elementos y el usuario se desplaza rápidamente por ellos mostrando totalmente el contenido de cada uno, se consumen muchos recursos de interfaz de usuario. Esto puede ofrecer una experiencia poco fluida con la interfaz de usuario. En función de la velocidad con que se desplace el usuario, es posible que muchos elementos nuevos aparezcan temporalmente en blanco o simplemente no se vean. Cuando sucede esto, puede que el usuario no esté seguro de si quedan más elementos. El usuario tiene que esperar hasta que la interfaz de usuario muestra completamente los nuevos elementos, si quedan, para poder verlos. Windows 8.1 mejora esta experiencia de presentación de elementos mediante marcadores de posición y actualizaciones incrementales de plantillas de datos.

Marcadores de posición

En Windows 8.1, cuando el usuario se desplaza rápidamente por un control ListView o GridView con muchos elementos, de manera predeterminada, la interfaz de usuario muestra un marcador de posición predeterminado para cada elemento siguiente hasta que la interfaz de usuario pueda mostrarlo por completo. Esto ofrece al usuario una indicación visual de que quedan elementos por mostrarse completamente. Estos marcadores de posición también pueden hacer que ListView o GridView aparezcan al usuario con mayor rapidez.

Los marcadores de posición están activados de manera predeterminada para las aplicaciones de la Tienda Windows que se ejecutan en Windows 8.1. Los marcadores de posición también se pueden activar de forma explícita si se establece la propiedad ShowsScrollingPlaceholders de los controles ListView o GridView en verdadero. Para desactivar los marcadores de posición de forma explícita, establece la propiedad ShowsScrollingPlaceholders de los controles ListView o GridView en falso.

Actualizaciones incrementales de plantillas de datos

Además de los marcadores de posición, puedes mostrar partes de un elemento en varias fases. Por ejemplo, en una lista de películas, podrías mostrar los títulos en la primera fase. Luego podrías mostrar sus clasificaciones en la segunda fase. En la tercera fase podrías mostrar una imagen del póster de la película, etc. Después de cada fase, el usuario sabe más sobre cada película rápidamente y puede seleccionar una de ellas antes de que se muestren los detalles de todas.

Windows 8.1 no puede saber de manera predeterminada qué parte de un elemento es más importante y se debe mostrar en primer lugar en tu aplicación, qué mostrar a continuación, etc. Para establecer este comportamiento, usa el evento ContainerContentChanging de los controles ListView o GridView para determinar qué parte de los elementos se mostrará en cada fase. Las actualizaciones incrementales de plantillas de datos están disponibles para todas las aplicaciones de la Tienda Windows que se compilan con Windows 8.1 como destino y que usan el evento ContainerContentChanging.

Para explorar este comportamiento, crea un nuevo proyecto de Microsoft Visual C# basado en la plantilla Aplicación vacía (XAML) y agrega este código y marcado.

  1. Agrega una clase llamada MyItem que represente un conjunto simulado de elementos.

    
    namespace LotsOfItems
    {
        public class MyItem
        {
            public string Title { get; set; }
            public string Subtitle { get; set; }
            public string Description { get; set; }
    
            public MyItem (string title, string subtitle, string description)
            {
                Title = title;
                Subtitle = subtitle;
                Description = description;
            }
        }
    }
    
    
    
  2. Agrega el marcado en lenguaje XAML al archivo MainPage.xaml predeterminado para mostrar una vista de cuadrícula y una plantilla para mostrar elementos. Establece el evento ContainerContentChanging del control GridView. Enlaza los controles de la plantilla para mostrar elementos a las propiedades de los elementos simulados, como Title, Subtitle y Description.

    
    <Page
            x:Class="LotsOfItems.MainPage"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="using:LotsOfItems"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            mc:Ignorable="d">
        <Grid>
            <GridView x:Name="myGridView"
                      ItemsSource="{Binding}"
                      Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
                      ContainerContentChanging="MyGridView_ContainerContentChanging">           
                <GridView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Height="100" 
                                    Width="100" 
                                    Background="Blue">
                            <Rectangle x:Name="placeholderRectangle" 
                                       Fill="Red" 
                                       Opacity="0"/>
                            <TextBlock x:Name="titleTextBlock" 
                                       Text="{Binding Title}" 
                                       Foreground="Yellow"/>
                            <TextBlock x:Name="subtitleTextBlock" 
                                       Text="{Binding Subtitle}" 
                                       Foreground="Aqua"/>
                            <TextBlock x:Name="descriptionTextBlock" 
                                       Text="{Binding Description}" 
                                       Foreground="Gray"/>
                        </StackPanel>
                    </DataTemplate>
                </GridView.ItemTemplate>
            </GridView>
        </Grid>   
    </Page>
    
    
    
  3. Agrega código al archivo MainPage.xaml.cs predeterminado para crear el conjunto simulado de elementos. Conecta el control GridView a la lista de elementos y responde al evento ContainerContentChanging del control GridView cuando el usuario se desplace rápidamente por la vista de cuadrícula.

    
    using System;
    using System.Collections.Generic;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Navigation;
    using Windows.UI.Xaml.Shapes;
    
    namespace LotsOfItems
    {
        public sealed partial class MainPage : Page
        {
            List<MyItem> myItems = new List<MyItem>(); 
    
            public MainPage()
            {
                CreateTestItems();
                this.InitializeComponent();
            }
    
            // Create a simulated list of 150,000 items.
            void CreateTestItems()
            {
                for (int i = 1; i < 150000; i++)
                {
                    myItems.Add(new MyItem(
                        "Title:" + i.ToString(), // Title.
                        "Sub:" + i.ToString(), // Subtitle.
                        "Desc:" + i.ToString())); // Description.                            
                }
            }
    
            // Connect the grid view to the list of items.
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                myGridView.ItemsSource = myItems;            
            }
    
            // Display each item incrementally to improve performance.
            private void MyGridView_ContainerContentChanging(
                    ListViewBase sender, 
                    ContainerContentChangingEventArgs args)
            {
                args.Handled = true;
    
                if (args.Phase != 0)
                {
                    throw new Exception("Not in phase 0.");
                }
    
                // First, show the items' placeholders.
                StackPanel templateRoot = 
                    (StackPanel)args.ItemContainer.ContentTemplateRoot;
                Rectangle placeholderRectangle = 
                    (Rectangle)templateRoot.FindName("placeholderRectangle");
                TextBlock titleTextBlock = 
                    (TextBlock)templateRoot.FindName("titleTextBlock");
                TextBlock subtitleTextBlock =
                    (TextBlock)templateRoot.FindName("subtitleTextBlock");
                TextBlock descriptionTextBlock =
                    (TextBlock)templateRoot.FindName("descriptionTextBlock");
    
                // Make the placeholder rectangle opaque.
                placeholderRectangle.Opacity = 1;
    
                // Make everything else invisible.
                titleTextBlock.Opacity = 0;
                subtitleTextBlock.Opacity = 0;
                descriptionTextBlock.Opacity = 0;
    
                // Show the items' titles in the next phase.
                args.RegisterUpdateCallback(ShowTitle);
            } 
           
            // Show the items' titles.
            private void ShowTitle(
                    ListViewBase sender, 
                    ContainerContentChangingEventArgs args)
            {
                if (args.Phase != 1)
                {
                    throw new Exception("Not in phase 1.");
                }
    
                // Next, show the items' titles. Keep everything else invisible.
                MyItem myItem = (MyItem)args.Item;
                SelectorItem itemContainer = 
                    (SelectorItem)args.ItemContainer;
                StackPanel templateRoot = 
                    (StackPanel)itemContainer.ContentTemplateRoot;
                TextBlock titleTextBlock = 
                    (TextBlock)templateRoot.FindName("titleTextBlock");
    
                titleTextBlock.Text = myItem.Title;
                titleTextBlock.Opacity = 1;
                
                // Show the items' subtitles in the next phase.
                args.RegisterUpdateCallback(ShowSubtitle);
            }
    
            // Show the items' subtitles.
            private void ShowSubtitle(
                    ListViewBase sender, 
                    ContainerContentChangingEventArgs args)
            {
                if (args.Phase != 2)
                {
                    throw new Exception("Not in phase 2.");
                }
    
                // Next, show the items' subtitles. Keep everything else invisible.
                MyItem myItem = (MyItem)args.Item;
                SelectorItem itemContainer = (SelectorItem)args.ItemContainer;
    
                StackPanel templateRoot = 
                    (StackPanel)itemContainer.ContentTemplateRoot;
                TextBlock subtitleTextBlock = 
                    (TextBlock)templateRoot.FindName("subtitleTextBlock");
    
                subtitleTextBlock.Text = myItem.Subtitle;
                subtitleTextBlock.Opacity = 1;
    
                // Show the items' descriptions in the next phase.
                args.RegisterUpdateCallback(ShowDescription);
            }
    
            // Show the items' descriptions.
            private void ShowDescription(
                    ListViewBase sender, 
                    ContainerContentChangingEventArgs args)
            {
                if (args.Phase != 3)
                {
                    throw new Exception("Not in phase 3.");
                }
    
                // Finally, show the items' descriptions. 
                MyItem myItem = (MyItem)args.Item;
                SelectorItem itemContainer = (SelectorItem)args.ItemContainer;
    
                StackPanel templateRoot = 
                    (StackPanel)itemContainer.ContentTemplateRoot;
                Rectangle placeholderRectangle = 
                    (Rectangle)templateRoot.FindName("placeholderRectangle");
                TextBlock descriptionTextBlock =
                    (TextBlock)templateRoot.FindName("descriptionTextBlock");
    
                descriptionTextBlock.Text = myItem.Description;
                descriptionTextBlock.Opacity = 1;
    
                // Make the placeholder rectangle invisible.
                placeholderRectangle.Opacity = 0;
            }
        }
    }
    
    
    
  4. Ejecuta la aplicación. Desplázate rápidamente por la vista de cuadrícula. Observa que, a medida que aparecen nuevos elementos en pantalla, los títulos aparecen en primer lugar, seguidos de los subtítulos y después las descripciones.
Nota  Para ver más código que muestra cómo llamar al evento ContainerContentChanging, consulta el ejemplo de XAML ListView y el GridViewejemplo de conceptos esenciales.

Temas relacionados

Cargar, almacenar y mostrar grandes conjuntos de datos de forma eficiente
Mejorar el tiempo de inicio de las aplicaciones con controles GridView y ListView

 

 

Mostrar:
© 2015 Microsoft