Xamarin.Forms CollectionView-Gruppierung

Große Datasets können häufig unübersichtlich werden, wenn sie in einer fortlaufenden Bildlaufliste angezeigt werden. In diesem Szenario kann das Organisieren der Daten in Gruppen die Benutzererfahrung verbessern, indem die Navigation in den Daten vereinfacht wird.

CollectionView unterstützt das Anzeigen gruppierter Daten und definiert die folgenden Eigenschaften, die steuern, wie sie dargestellt werden:

  • IsGrouped, vom Typ bool, gibt an, ob die zugrunde liegenden Daten in Gruppen angezeigt werden sollen. Der Standardwert dieser Eigenschaft ist false.
  • GroupHeaderTemplate, vom Typ DataTemplate, die Vorlage, die für die Kopfzeile jeder Gruppe verwendet werden soll.
  • GroupFooterTemplate, vom Typ DataTemplate, die Vorlage, die für die Fußzeile jeder Gruppe verwendet werden soll.

Diese Eigenschaften werden durch BindableProperty-Objekte unterstützt, was bedeutet, dass die Eigenschaften Ziele von Datenbindungen sein können.

Die folgenden Screenshots zeigen eine CollectionView anzeige gruppierte Daten:

Screenshot einer gruppierten Daten in einer CollectionView unter iOS und Android

Weitere Informationen zu Datenvorlagen finden Sie unter Xamarin.Forms-Datenvorlagen.

Gruppieren von Daten

Die Daten müssen gruppiert werden, bevor sie angezeigt werden können. Dies kann durch Erstellen einer Liste von Gruppen erreicht werden, wobei jede Gruppe eine Liste von Elementen ist. Die Liste der Gruppen sollte eine IEnumerable<T>-Auflistung sein, in der T zwei Datenteile definiert:

  • Ein Gruppenname.
  • Eine IEnumerable-Auflistung, die die Elemente definiert, die zur Gruppe gehören.

Der Prozess zum Gruppieren von Daten dient daher Folgendem:

  • Erstellen eines Typs, der ein einzelnes Element modelliert.
  • Erstellen eines Typs, der eine einzelne Gruppe von Elementen modelliert.
  • Erstellen einer IEnumerable<T>-Sammlung, wobei es sich bei T um den Typ handelt, der eine einzelne Gruppe von Elementen modelliert. Diese Sammlung ist daher eine Sammlung von Gruppen, die die gruppierten Daten speichert.
  • Hinzufügen von Daten zur IEnumerable<T>-Auflistung.

Beispiel

Beim Gruppieren von Daten besteht der erste Schritt darin, einen Typ zu erstellen, der ein einzelnes Element modelliert. Das folgende Beispiel zeigt die Klasse Animal der Beispiel-App:

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

Die Klasse Animal modelliert ein einzelnes Element. Anschließend kann ein Typ erstellt werden, der eine Gruppe von Elementen modelliert. Das folgende Beispiel zeigt die Klasse AnimalGroup der Beispiel-App:

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

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

Die Klasse AnimalGroup erbt von der Klasse List<T> und fügt eine Name-Eigenschaft hinzu, die den Gruppennamen darstellt.

Anschließend kann eine IEnumerable<T>-Auflistung von Gruppen erstellt werden:

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

Dieser Code definiert eine Auflistung namens Animals, wobei jedes Element in der Auflistung ein AnimalGroup-Objekt ist. Jedes AnimalGroup-Objekt besteht aus einem Namen und einer List<Animal>-Auflistung, die die Animal-Objekte in der Gruppe definiert.

Gruppierte Daten können dann der Animals-Auflistung hinzugefügt werden:

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

Dieser Code erstellt zwei Gruppen in der Animals-Auflistung. Der erste AnimalGroup wird Bears genannt und enthält eine List<Animal>-Auflistung von Bärendetails. Die zweite AnimalGroup wird Monkeys genannt und enthält eine List<Animal>-Sammlung von Affendetails.

Gruppierte Daten anzeigen

CollectionView zeigt gruppierte Daten an, vorausgesetzt, die Daten wurden ordnungsgemäß gruppiert, indem sie die Eigenschaft IsGrouped auf true gesetzt wurde:

<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>

Der entsprechende C#-Code lautet:

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

Die Darstellung der einzelnen Elemente in der CollectionView wird durch Festlegen der Eigenschaft CollectionView.ItemTemplate auf eine DataTemplate definiert. Weitere Informationen finden Sie unter Definieren der Darstellung des Elements.

Hinweis

CollectionView zeigt den Gruppennamen standardmäßig in der Kopf- und Fußzeile der Gruppe an. Dieses Verhalten kann durch Anpassen der Kopf- und Fußzeile der Gruppe geändert werden.

Anpassen der Kopfzeile der Gruppe

Das Aussehen jeder Gruppenüberschrift kann angepasst werden, indem die Eigenschaft CollectionView.GroupHeaderTemplate auf DataTemplate gesetzt wird:

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

In diesem Beispiel wird jeder Gruppenkopf auf ein Label gesetzt, das den Gruppennamen anzeigt und für das andere Darstellungseigenschaften festgelegt sind. Die folgenden Screenshots zeigen den angepassten Gruppenkopf:

Screenshot eines angepassten Gruppenkopfs in einer CollectionView unter iOS und Android

Die Darstellung der jeweiligen Gruppenfußzeile kann angepasst werden, indem Sie die CollectionView.GroupFooterTemplate-Eigenschaft auf eine DataTemplate festlegen:

<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 diesem Beispiel wird jede Gruppenfußzeile auf ein Label festgelegt, das die Anzahl der Elemente in der Gruppe anzeigt. Die folgenden Screenshots zeigen die angepasste Gruppenfußzeile:

Screenshot einer angepassten Gruppenfußzeile in einer CollectionView unter iOS und Android

Leere Gruppen

Wenn eine CollectionView gruppierte Daten anzeigt, werden alle Gruppen dargestellt, die leer sind. Solche Gruppen werden mit einer Gruppenkopfzeile und einer Gruppenfußzeile angezeigt, die angeben, dass die Gruppe leer ist. Die folgenden Screenshots zeigen eine leere Gruppe:

Screenshot einer leeren Gruppe in einer CollectionView unter iOS und Android

Hinweis

Unter iOS 10 und niedriger werden Gruppenkopf- und Fußzeilen für leere Gruppen möglicherweise oben im CollectionViewBereich angezeigt.

Gruppieren ohne Vorlagen

CollectionView kann korrekt gruppierte Daten anzeigen, ohne die Eigenschaft CollectionView.ItemTemplate auf DataTemplate festzulegen:

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

In diesem Fall können aussagekräftige Daten angezeigt werden, indem Sie die ToString-Methode bei dem Typ außer Kraft setzen, der ein einzelnes Element modelliert, sowie bei dem Typ, der eine einzelne Gruppe von Elementen modelliert.