Xamarin.Forms Raggruppamento CollectionView

I set di dati di grandi dimensioni possono spesso diventare difficili quando vengono presentati in un elenco a scorrimento continuo. In questo scenario, l'organizzazione dei dati in gruppi può migliorare l'esperienza utente semplificando l'esplorazione dei dati.

CollectionView supporta la visualizzazione di dati raggruppati e definisce le proprietà seguenti che controllano la modalità di presentazione:

  • IsGrouped, di tipo bool, indica se i dati sottostanti devono essere visualizzati in gruppi. Il valore predefinito di questa proprietà è false.
  • GroupHeaderTemplate, di tipo DataTemplate, il modello da usare per l'intestazione di ogni gruppo.
  • GroupFooterTemplate, di tipo DataTemplate, il modello da usare per il piè di pagina di ogni gruppo.

Queste proprietà sono supportate da BindableProperty oggetti , il che significa che le proprietà possono essere destinazioni di data binding.

Gli screenshot seguenti mostrano una CollectionView visualizzazione dei dati raggruppati:

Screenshot di dati raggruppati in un oggetto CollectionView, in iOS e Android

Per altre informazioni sui modelli di dati, vedere Xamarin.Forms Modelli di dati.

Raggruppare i dati

I dati devono essere raggruppati prima di poter essere visualizzati. A tale scopo, è possibile creare un elenco di gruppi, in cui ogni gruppo è un elenco di elementi. L'elenco dei gruppi deve essere una IEnumerable<T> raccolta, in cui T definisce due parti di dati:

  • Nome del gruppo.
  • Raccolta IEnumerable che definisce gli elementi appartenenti al gruppo.

Il processo di raggruppamento dei dati è quindi:

  • Creare un tipo che modella un singolo elemento.
  • Creare un tipo che modella un singolo gruppo di elementi.
  • Creare una IEnumerable<T> raccolta, dove T è il tipo che modella un singolo gruppo di elementi. Questa raccolta è quindi una raccolta di gruppi, che archivia i dati raggruppati.
  • Aggiungere dati alla IEnumerable<T> raccolta.

Esempio

Quando si raggruppano i dati, il primo passaggio consiste nel creare un tipo che modella un singolo elemento. L'esempio seguente illustra la Animal classe dell'applicazione di esempio:

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

La Animal classe modella un singolo elemento. È quindi possibile creare un tipo che modella un gruppo di elementi. L'esempio seguente illustra la AnimalGroup classe dell'applicazione di esempio:

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

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

La AnimalGroup classe eredita dalla List<T> classe e aggiunge una Name proprietà che rappresenta il nome del gruppo.

È quindi possibile creare una IEnumerable<T> raccolta di gruppi:

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

Questo codice definisce una raccolta denominata Animals, in cui ogni elemento dell'insieme è un AnimalGroup oggetto . Ogni AnimalGroup oggetto comprende un nome e una List<Animal> raccolta che definisce gli Animal oggetti nel gruppo.

I dati raggruppati possono quindi essere aggiunti alla Animals raccolta:

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"
    },
    // ...
}));

Questo codice crea due gruppi nella Animals raccolta. Il primo AnimalGroup è denominato Bearse contiene una List<Animal> raccolta di dettagli dell'orso. Il secondo AnimalGroup è denominato Monkeyse contiene una List<Animal> raccolta di dettagli della scimmia.

Visualizzare i dati raggruppati

CollectionView visualizzerà i dati raggruppati, purché i dati siano stati raggruppati correttamente, impostando la IsGrouped proprietà su 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>

Il codice C# equivalente è il seguente:

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

L'aspetto di ogni elemento in CollectionView è definito impostando la CollectionView.ItemTemplate proprietà su un oggetto DataTemplate. Per altre informazioni, vedere Definire l'aspetto dell'elemento.

Nota

Per impostazione predefinita, CollectionView visualizzerà il nome del gruppo nell'intestazione e nel piè di pagina del gruppo. Questo comportamento può essere modificato personalizzando l'intestazione del gruppo e il piè di pagina del gruppo.

Personalizzare l'intestazione del gruppo

L'aspetto di ogni intestazione di gruppo può essere personalizzato impostando la CollectionView.GroupHeaderTemplate proprietà su :DataTemplate

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

In questo esempio, ogni intestazione di gruppo è impostata su un Label oggetto che visualizza il nome del gruppo e con altre proprietà di aspetto impostate. Gli screenshot seguenti mostrano l'intestazione del gruppo personalizzata:

Screenshot di un'intestazione di gruppo personalizzata in un controllo CollectionView in iOS e Android

L'aspetto di ogni piè di pagina del gruppo può essere personalizzato impostando la CollectionView.GroupFooterTemplate proprietà su :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>

In questo esempio, ogni piè di pagina del gruppo è impostato su un Label che visualizza il numero di elementi nel gruppo. Gli screenshot seguenti mostrano il piè di pagina del gruppo personalizzato:

Screenshot di un piè di pagina del gruppo personalizzato in un controllo CollectionView in iOS e Android

Gruppi vuoti

Quando un CollectionView oggetto visualizza i dati raggruppati, verranno visualizzati tutti i gruppi vuoti. Tali gruppi verranno visualizzati con un'intestazione e un piè di pagina del gruppo, a indicare che il gruppo è vuoto. Gli screenshot seguenti mostrano un gruppo vuoto:

Screenshot di un gruppo vuoto in un oggetto CollectionView, in iOS e Android

Nota

In iOS 10 e versioni precedenti, le intestazioni di gruppo e i piè di pagina per i gruppi vuoti possono essere tutte visualizzate nella parte superiore di CollectionView.

Raggruppare senza modelli

CollectionViewpuò visualizzare correttamente i dati raggruppati senza impostare la CollectionView.ItemTemplate proprietà su :DataTemplate

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

In questo scenario è possibile visualizzare dati significativi eseguendo l'override del ToString metodo nel tipo che modella un singolo elemento e il tipo che modella un singolo gruppo di elementi.