Teilen über


Xamarin.Forms CollectionView-Daten

CollectionView enthält die folgenden Eigenschaften, die die anzuzeigenden Daten und deren Darstellung definieren:

  • ItemsSource, vom Typ IEnumerable, gibt die Sammlung der anzuzeigenden Elemente an und hat den Standardwert null.
  • ItemTemplate, vom Typ DataTemplate, gibt die Vorlage an, die auf jedes Element in der Sammlung der anzuzeigenden Elemente anzuwenden ist.

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

Hinweis

CollectionView definiert eine ItemsUpdatingScrollMode-Eigenschaft, die das Bildlaufverhalten des CollectionView darstellt, wenn neue Elemente hinzugefügt werden. Weitere Informationen zu dieser Eigenschaft finden Sie unter Steuerung der Bildlaufposition, wenn neue Elemente hinzugefügt werden.

CollectionView unterstützt die inkrementelle Datenvirtualisierung, wenn der/die Benutzer*in blättert. Weitere Informationen finden Sie unter Inkrementelles Laden von Daten.

Auffüllen einer CollectionView mit Daten

Ein CollectionView wird mit Daten gefüllt, indem seine ItemsSource-Eigenschaft auf eine beliebige Sammlung gesetzt wird, die IEnumerable implementiert. Standardmäßig zeigt CollectionView Elemente in einer vertikalen Liste an.

Wichtig

Wenn die CollectionView aktualisiert werden muss, wenn Elemente hinzugefügt, entfernt oder in der zugrunde liegenden Sammlung geändert werden, sollte die zugrunde liegende Sammlung eine IEnumerable-Sammlung sein, die Benachrichtigungen über Eigenschaftsänderungen sendet, wie etwa ObservableCollection.

CollectionView kann mit Daten gefüllt werden, indem seine ItemsSource-Eigenschaft mithilfe von Datenbindung an eine IEnumerable-Sammlung gebunden wird. In XAML wird dies mit der Markuperweiterung Binding erreicht:

<CollectionView ItemsSource="{Binding Monkeys}" />

Der entsprechende C#-Code lautet:

CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

In diesem Beispiel binden die ItemsSource-Eigenschaftsdaten an die Monkeys-Eigenschaft des verbundenen Viewmodels.

Hinweis

Kompilierte Bindungen können aktiviert werden, um die Datenbindungsleistung in Xamarin.Forms Anwendungen zu verbessern. Weitere Informationen finden Sie unter Kompilierte Bindungen.

Informationen zum Ändern des CollectionView Layouts finden Sie unter Xamarin.Forms CollectionView Layout. Für Informationen darüber, wie man das Aussehen der einzelnen Elemente in CollectionView definiert, siehe Aussehen von Elementen definieren. Weitere Informationen zur Datenbindung finden Sie unter Xamarin.Forms-Datenbindung.

Warnung

CollectionView löst eine Ausnahme aus, wenn ItemsSource aus dem UI-Thread aktualisiert wird.

Definieren der Darstellung des Elements

Das Aussehen der einzelnen Elemente in der CollectionView kann durch die Einstellung der CollectionView.ItemTemplate-Eigenschaft auf eine DataTemplate definiert werden:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <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();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

collectionView.ItemTemplate = new DataTemplate(() =>
{
    Grid grid = new Grid { Padding = 10 };
    grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
    grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

    Image image = new Image { Aspect = Aspect.AspectFill, HeightRequest = 60, WidthRequest = 60 };
    image.SetBinding(Image.SourceProperty, "ImageUrl");

    Label nameLabel = new Label { FontAttributes = FontAttributes.Bold };
    nameLabel.SetBinding(Label.TextProperty, "Name");

    Label locationLabel = new Label { FontAttributes = FontAttributes.Italic, VerticalOptions = LayoutOptions.End };
    locationLabel.SetBinding(Label.TextProperty, "Location");

    Grid.SetRowSpan(image, 2);

    grid.Children.Add(image);
    grid.Children.Add(nameLabel, 1, 0);
    grid.Children.Add(locationLabel, 1, 1);

    return grid;
});

Die im DataTemplate angegebenen Elemente bestimmen die Darstellung der einzelnen Elemente in der Liste. In diesem Beispiel wird das Layout innerhalb des DataTemplate durch ein Grid verwaltet. Die Grid enthält ein Image-Objekt und zwei Label-Objekte, die alle an Eigenschaften der Monkey-Klasse gebunden sind:

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

Die folgenden Screenshots zeigen das Ergebnis der Vorlagen für jedes Element in der Liste:

Screenshot der Sammlungsansicht, in der jedes Element vorlagen, unter iOS und Android

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

Auswählen der Elementdarstellung zur Runtime

Die Darstellung jedes Elements in der CollectionView kann zur Laufzeit auf der Grundlage des Elementwerts gewählt werden, indem die Eigenschaft CollectionView.ItemTemplate auf ein DataTemplateSelector-Objekt gesetzt wird:

<ContentPage ...
             xmlns:controls="clr-namespace:CollectionViewDemos.Controls">
    <ContentPage.Resources>
        <DataTemplate x:Key="AmericanMonkeyTemplate">
            ...
        </DataTemplate>

        <DataTemplate x:Key="OtherMonkeyTemplate">
            ...
        </DataTemplate>

        <controls:MonkeyDataTemplateSelector x:Key="MonkeySelector"
                                             AmericanMonkey="{StaticResource AmericanMonkeyTemplate}"
                                             OtherMonkey="{StaticResource OtherMonkeyTemplate}" />
    </ContentPage.Resources>

    <CollectionView ItemsSource="{Binding Monkeys}"
                    ItemTemplate="{StaticResource MonkeySelector}" />
</ContentPage>

Der entsprechende C#-Code lautet:

CollectionView collectionView = new CollectionView
{
    ItemTemplate = new MonkeyDataTemplateSelector { ... }
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Die ItemTemplate-Eigenschaft wird auf ein MonkeyDataTemplateSelector-Objekt gesetzt. Das folgende Beispiel zeigt die Klasse MonkeyDataTemplateSelector:

public class MonkeyDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate AmericanMonkey { get; set; }
    public DataTemplate OtherMonkey { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        return ((Monkey)item).Location.Contains("America") ? AmericanMonkey : OtherMonkey;
    }
}

Die Klasse MonkeyDataTemplateSelector definiert AmericanMonkey und OtherMonkeyDataTemplate Eigenschaften, die auf verschiedene Datenvorlagen gesetzt werden. Die OnSelectTemplate-Überschreibung gibt die AmericanMonkey-Vorlage zurück, die den Namen des Affen und den Ort in blaugrüner Farbe anzeigt, wenn der Name des Affen „Amerika“ enthält. Wenn der Name des Affen nicht „Amerika“ enthält, gibt die OnSelectTemplate-Überschreibung die OtherMonkey-Vorlage zurück, die den Namen des Affen und den Ort in Silber anzeigt:

Screenshot der SammlungView-Laufzeitelementvorlagenauswahl unter iOS und Android

Weitere Informationen zu Datenvorlagenselektoren finden Sie unter Create a Xamarin.Forms DataTemplateSelector.

Wichtig

Wenn Sie CollectionView verwenden, setzen Sie das Stammelement Ihrer DataTemplate-Objekte niemals auf eine ViewCell. Dies wird zu einer Ausnahme führen, da CollectionView kein Verständnis von Zellen hat.

Kontextmenüs

CollectionView unterstützt Kontextmenüs für Datenelemente durch die SwipeView, die das Kontextmenü mit einer Wischgeste öffnet. SwipeView ist ein Container-Steuerelement, das ein Inhaltselement umschließt und Kontextmenüelemente für dieses Inhaltselement bereitstellt. Daher werden Kontextmenüs für ein CollectionView implementiert, indem ein SwipeView erstellt wird, das den Inhalt definiert, um den sich das SwipeView wickelt, sowie die Kontextmenüelemente, die durch die Wischgeste angezeigt werden. Dies wird erreicht, indem die SwipeView als Stammansicht in der DataTemplate festgelegt wird, die das Erscheinungsbild der einzelnen Datenelemente in der CollectionView definiert:

<CollectionView x:Name="collectionView"
                ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <SwipeView>
                <SwipeView.LeftItems>
                    <SwipeItems>
                        <SwipeItem Text="Favorite"
                                   IconImageSource="favorite.png"
                                   BackgroundColor="LightGreen"
                                   Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.FavoriteCommand}"
                                   CommandParameter="{Binding}" />
                        <SwipeItem Text="Delete"
                                   IconImageSource="delete.png"
                                   BackgroundColor="LightPink"
                                   Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.DeleteCommand}"
                                   CommandParameter="{Binding}" />
                    </SwipeItems>
                </SwipeView.LeftItems>
                <Grid BackgroundColor="White"
                      Padding="10">
                    <!-- Define item appearance -->
                </Grid>
            </SwipeView>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Der entsprechende C#-Code lautet:

CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

collectionView.ItemTemplate = new DataTemplate(() =>
{
    // Define item appearance
    Grid grid = new Grid { Padding = 10, BackgroundColor = Color.White };
    // ...

    SwipeView swipeView = new SwipeView();
    SwipeItem favoriteSwipeItem = new SwipeItem
    {
        Text = "Favorite",
        IconImageSource = "favorite.png",
        BackgroundColor = Color.LightGreen
    };
    favoriteSwipeItem.SetBinding(MenuItem.CommandProperty, new Binding("BindingContext.FavoriteCommand", source: collectionView));
    favoriteSwipeItem.SetBinding(MenuItem.CommandParameterProperty, ".");

    SwipeItem deleteSwipeItem = new SwipeItem
    {
        Text = "Delete",
        IconImageSource = "delete.png",
        BackgroundColor = Color.LightPink
    };
    deleteSwipeItem.SetBinding(MenuItem.CommandProperty, new Binding("BindingContext.DeleteCommand", source: collectionView));
    deleteSwipeItem.SetBinding(MenuItem.CommandParameterProperty, ".");

    swipeView.LeftItems = new SwipeItems { favoriteSwipeItem, deleteSwipeItem };
    swipeView.Content = grid;    
    return swipeView;
});

In diesem Beispiel ist der SwipeView-Inhalt ein Grid, der das Aussehen jedes Elements im CollectionView definiert. Die Wischelemente werden verwendet, um Aktionen auf dem SwipeView-Inhalt auszuführen, und werden angezeigt, wenn das Steuerelement von der linken Seite gewischt wird:

Screenshot der Kontextmenüelemente von CollectionView unter iOS und Android

SwipeView unterstützt vier verschiedene Wischrichtungen, wobei die Wischrichtung durch die richtungsbezogene SwipeItems-Sammlung definiert wird, der die SwipeItems-Objekte hinzugefügt werden. Standardmäßig wird ein Wischelement ausgeführt, wenn es von Benutzer*innen angetippt wird. Außerdem werden nach der Ausführung eines Wischvorgangs die Wischvorgänge ausgeblendet und der SwipeView-Inhalt wird wieder angezeigt. Diese Verhaltensweisen können jedoch geändert werden.

Weitere Informationen zum SwipeView Steuerelement finden Sie unter Xamarin.Forms SwipeView.

Aktualisierung durch Ziehen

CollectionView unterstützt die Pull-to-Refresh-Funktionalität durch die RefreshView, die es ermöglicht, die angezeigten Daten durch Ziehen nach unten auf der Liste der Elemente zu aktualisieren. Das RefreshView ist ein Container-Steuerelement, das seinem untergeordneten Element eine Pull-to-Refresh-Funktionalität bietet, vorausgesetzt, das untergeordnete Element unterstützt scrolbare Inhalte. Daher wird Pull-to-Refresh für eine CollectionView implementiert, indem sie als untergeordnetes Element einer RefreshView festgelegt wird:

<RefreshView IsRefreshing="{Binding IsRefreshing}"
             Command="{Binding RefreshCommand}">
    <CollectionView ItemsSource="{Binding Animals}">
        ...
    </CollectionView>
</RefreshView>

Der entsprechende C#-Code lautet:

RefreshView refreshView = new RefreshView();
ICommand refreshCommand = new Command(() =>
{
    // IsRefreshing is true
    // Refresh data here
    refreshView.IsRefreshing = false;
});
refreshView.Command = refreshCommand;

CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
refreshView.Content = collectionView;
// ...

Wenn der/die Benutzer*in eine Aktualisierung veranlasst, wird der durch die Command-Eigenschaft definierte ICommand ausgeführt, der die angezeigten Elemente aktualisieren sollte. Während des Aktualisierungsvorgangs wird eine Visualisierung angezeigt, die aus einem animierten Fortschrittskreis besteht:

Screenshot der Pull-to-Refresh-Version von CollectionView unter iOS und Android

Der Wert der Eigenschaft RefreshView.IsRefreshing zeigt den aktuellen Zustand des RefreshView an. Wenn eine Aktualisierung durch den/die Benutzer*in ausgelöst wird, wechselt diese Eigenschaft automatisch zu true. Sobald die Aktualisierung abgeschlossen ist, sollten Sie die Eigenschaft auf false zurücksetzen.

Weitere Informationen RefreshViewfinden Sie unter Xamarin.Forms RefreshView.

Daten inkrementell laden

CollectionView unterstützt die inkrementelle Datenvirtualisierung, wenn der/die Benutzer*in blättert. Dies ermöglicht Szenarien wie das asynchrone Laden einer Seite mit Daten aus einem Webdienst, während der/die Benutzer*in scrollt. Außerdem kann der Punkt, an dem weitere Daten geladen werden, konfiguriert werden, so dass die Benutzer*innen keine leeren Stellen sehen oder vom Scrollen abgehalten werden.

CollectionView definiert die folgenden Eigenschaften zur Steuerung des inkrementellen Ladens von Daten:

  • RemainingItemsThreshold, vom Typ int, der Schwellenwert der noch nicht sichtbaren Elemente in der Liste, bei dem das Ereignis RemainingItemsThresholdReached ausgelöst wird.
  • RemainingItemsThresholdReachedCommand vom Typ ICommand, der ausgeführt wird, wenn der RemainingItemsThreshold erreicht wird.
  • RemainingItemsThresholdReachedCommandParameter, vom Typ object: Parameter, der an den RemainingItemsThresholdReachedCommand übergeben wird.

CollectionView definiert auch ein RemainingItemsThresholdReached-Ereignis, das ausgelöst wird, wenn das CollectionView so weit gescrollt wird, dass RemainingItemsThreshold-Elemente nicht mehr angezeigt wurden. Dieses Ereignis kann zum Laden weiterer Elemente verwendet werden. Wenn das RemainingItemsThresholdReached-Ereignis ausgelöst wird, wird außerdem RemainingItemsThresholdReachedCommand ausgeführt, wodurch ein inkrementelles Laden von Daten in einem Viewmodel möglich wird.

Der Standardwert der Eigenschaft RemainingItemsThreshold ist -1, was bedeutet, dass das Ereignis RemainingItemsThresholdReached nie ausgelöst wird. Wenn der Eigenschaftswert 0 ist, wird das Ereignis RemainingItemsThresholdReached ausgelöst, wenn das letzte Element in ItemsSource angezeigt wird. Bei Werten größer als 0 wird das Ereignis RemainingItemsThresholdReached ausgelöst, wenn ItemsSource die Anzahl der Elemente enthält, zu denen noch nicht gescrollt wurde.

Hinweis

CollectionView validiert die Eigenschaft RemainingItemsThreshold, so dass ihr Wert immer größer oder gleich -1 ist.

Das folgende XAML-Beispiel zeigt ein CollectionView, das Daten inkrementell lädt:

<CollectionView ItemsSource="{Binding Animals}"
                RemainingItemsThreshold="5"
                RemainingItemsThresholdReached="OnCollectionViewRemainingItemsThresholdReached">
    ...
</CollectionView>

Der entsprechende C#-Code lautet:

CollectionView collectionView = new CollectionView
{
    RemainingItemsThreshold = 5
};
collectionView.RemainingItemsThresholdReached += OnCollectionViewRemainingItemsThresholdReached;
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");

In diesem Codebeispiel wird das RemainingItemsThresholdReached-Ereignis ausgelöst, wenn fünf Elemente vorhanden sind, durch die noch nicht gescrollt wurde. Als Reaktion darauf wird der OnCollectionViewRemainingItemsThresholdReached-Ereignishandler ausgeführt:

void OnCollectionViewRemainingItemsThresholdReached(object sender, EventArgs e)
{
    // Retrieve more data here and add it to the CollectionView's ItemsSource collection.
}

Hinweis

Die Daten können auch schrittweise geladen werden, indem die RemainingItemsThresholdReachedCommand an eine ICommand-Implementierung im ViewModel gebunden wird.