Compartir vía


Visualización de datos agrupados en CollectionView

Browse sample. Examina la muestra

Los conjuntos de datos de gran tamaño se pueden volver difíciles de manejar cuando se presentan en una lista de desplazamiento continuo. En este escenario, la agrupación de los datos puede mejorar la experiencia del usuario al facilitar la navegación.

NET Multi-platform App UI (.NET MAUI) CollectionView admite la visualización de datos agrupados y define las siguientes propiedades que controlan cómo se presentará:

  • IsGrouped, de tipo bool, indica si los datos subyacentes deben mostrarse en grupos. El valor predeterminado de esta propiedad es false.
  • GroupHeaderTemplate, de tipo DataTemplate, la plantilla que se va a usar para el encabezado de cada grupo.
  • GroupFooterTemplate, de tipo DataTemplate, la plantilla que se va a usar para el pie de página de cada grupo.

Todas estas propiedades están respaldadas por objetos BindableProperty, lo que significa que las propiedades pueden ser destinos de los enlaces de datos.

En la captura de pantalla siguiente se muestra un elemento CollectionView que muestra datos agrupados:

Screenshot of grouped data in a CollectionView.

Para obtener más información sobre las plantillas de datos, consulta Plantillas de datos.

Agrupación de datos

Los datos se deben agrupar antes de que se puedan mostrar. Esto se puede lograr mediante la creación de una lista de grupos, donde cada grupo es una lista de elementos. La lista de grupos debe ser una colección de IEnumerable<T>, donde T define dos fragmentos de datos:

  • Un nombre de grupo.
  • Una colección IEnumerable que define los elementos que pertenecen al grupo.

El proceso de agrupación de datos, por lo tanto, consiste en:

  • Crear un tipo que modele un solo elemento.
  • Crear un tipo que modele un único grupo de elementos.
  • Crear una colección IEnumerable<T>, donde T es el tipo que modela un único grupo de elementos. Esta colección es una colección de grupos, que almacena los datos agrupados.
  • Agregar datos a la colección IEnumerable<T>.

Ejemplo

Al agrupar datos, el primer paso es crear un tipo que modele un solo elemento. El ejemplo siguiente muestra la clase Animal para la aplicación de ejemplo:

public class Animal
{
    public string Name { get; set; }
    public string Location { get; set; }
    public string Details { get; set; }
    public string ImageUrl { get; set; }
}

La clase Animal modela un solo elemento. Luego se puede crear un tipo que modele un grupo de elementos. El ejemplo siguiente muestra la clase AnimalGroup de la aplicación de ejemplo:

public class AnimalGroup : List<Animal>
{
    public string Name { get; private set; }

    public AnimalGroup(string name, List<Animal> animals) : base(animals)
    {
        Name = name;
    }
}

La clase AnimalGroup hereda de la clase List<T> y agrega una propiedad Name que representa el nombre del grupo.

Después, se puede crear una colección de grupos IEnumerable<T>:

public List<AnimalGroup> Animals { get; private set; } = new List<AnimalGroup>();

Este código define una colección llamada Animals, donde cada elemento de la colección es un objeto AnimalGroup. Cada objeto AnimalGroup consta de un nombre y una colección List<Animal> que define los objetos del grupo Animal.

Después los datos agrupados se pueden agregar a la colección Animals:

Animals.Add(new AnimalGroup("Bears", new List<Animal>
{
    new Animal
    {
        Name = "American Black Bear",
        Location = "North America",
        Details = "Details about the bear go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/0/08/01_Schwarzbär.jpg"
    },
    new Animal
    {
        Name = "Asian Black Bear",
        Location = "Asia",
        Details = "Details about the bear go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG/180px-Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG"
    },
    // ...
}));

Animals.Add(new AnimalGroup("Monkeys", new List<Animal>
{
    new Animal
    {
        Name = "Baboon",
        Location = "Africa & Asia",
        Details = "Details about the monkey go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
    },
    new Animal
    {
        Name = "Capuchin Monkey",
        Location = "Central & South America",
        Details = "Details about the monkey go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Capuchin_Costa_Rica.jpg/200px-Capuchin_Costa_Rica.jpg"
    },
    new Animal
    {
        Name = "Blue Monkey",
        Location = "Central and East Africa",
        Details = "Details about the monkey go here.",
        ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/BlueMonkey.jpg/220px-BlueMonkey.jpg"
    },
    // ...
}));

Este código crea dos grupos en la colección Animals. El primer grupo AnimalGroup se llama Bears y contiene una colección List<Animal> de detalles del portador. El segundo AnimalGroup se llama Monkeys y contiene una colección List<Animal> de detalles de mono.

Visualización de datos agrupados

CollectionView mostrará los datos agrupados, siempre que los datos se hayan agrupado correctamente, estableciendo la propiedad IsGrouped en true:

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="10">
                ...
                <Image Grid.RowSpan="2"
                       Source="{Binding ImageUrl}"
                       Aspect="AspectFill"
                       HeightRequest="60"
                       WidthRequest="60" />
                <Label Grid.Column="1"
                       Text="{Binding Name}"
                       FontAttributes="Bold" />
                <Label Grid.Row="1"
                       Grid.Column="1"
                       Text="{Binding Location}"
                       FontAttributes="Italic"
                       VerticalOptions="End" />
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

El código de C# equivalente es el siguiente:

CollectionView collectionView = new CollectionView
{
    IsGrouped = true
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
// ...

La apariencia de cada elemento en CollectionView se define estableciendo la propiedad CollectionView.ItemTemplate en DataTemplate. Para obtener más información, consulta Definir la apariencia del elemento.

Nota:

De forma predeterminada, CollectionView mostrará el nombre del grupo en el encabezado y pie de página del grupo. Este comportamiento se puede cambiar personalizando el encabezado de grupo y el pie de página de grupo.

Personalización del encabezado de grupo

Se puede personalizar la apariencia de cada encabezado de grupo estableciendo la propiedad CollectionView.GroupHeaderTemplate en un objeto DataTemplate:

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true">
    ...
    <CollectionView.GroupHeaderTemplate>
        <DataTemplate>
            <Label Text="{Binding Name}"
                   BackgroundColor="LightGray"
                   FontSize="18"
                   FontAttributes="Bold" />
        </DataTemplate>
    </CollectionView.GroupHeaderTemplate>
</CollectionView>

En este ejemplo, cada encabezado de grupo se establece en Label que muestra el nombre del grupo y que tiene otras propiedades de apariencia establecidas. En la captura de pantalla siguiente se muestra el encabezado de grupo personalizado:

Screenshot of a customized group header in a CollectionView.

Se puede personalizar la apariencia de cada pie de página del grupo estableciendo la propiedad CollectionView.GroupFooterTemplate en DataTemplate:

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true">
    ...
    <CollectionView.GroupFooterTemplate>
        <DataTemplate>
            <Label Text="{Binding Count, StringFormat='Total animals: {0:D}'}"
                   Margin="0,0,0,10" />
        </DataTemplate>
    </CollectionView.GroupFooterTemplate>
</CollectionView>

En este ejemplo, cada pie de página del grupo se establece en un objeto Label que muestra el número de elementos del grupo. En la captura de pantalla siguiente se muestra el pie de página del grupo personalizado:

Screenshot of customized group footer in a CollectionView.

Grupos vacíos

Cuando CollectionView muestra datos agrupados, se mostrarán todos los grupos que estén vacíos. Estos grupos se mostrarán con un encabezado de grupo y un pie de página, lo que indica que el grupo está vacío. En la siguiente captura de pantalla se muestra un grupo vacío:

Screenshot of an empty group in a CollectionView.

Nota:

En iOS 10, los encabezados y pies de página de grupo de los grupos vacíos pueden mostrarse en la parte superior de CollectionView.

Agrupar sin plantillas

CollectionView puede mostrar datos agrupados correctamente sin establecer la propiedad CollectionView.ItemTemplate en DataTemplate:

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true" />

En este escenario, se pueden mostrar datos significativos reemplazando el método ToString en el tipo que modela un solo elemento y el tipo que modela un único grupo de elementos.