Auffüllen einer CollectionView mit Daten
Die .NET Multi-Platform App UI CollectionView (.NET MAUI) enthält die folgenden Eigenschaften, die die anzuzeigenden Daten und ihr Aussehen definieren:
ItemsSource
, vom TypIEnumerable
, gibt die Sammlung der anzuzeigenden Elemente an und hat den Standardwertnull
.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.
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 Leistung der Datenbindung in .NET MAUI-Anwendungen zu verbessern. Für weitere Informationen siehe Kompilierte Bindungen.
Informationen zum Ändern des CollectionView-Layouts finden Sie unter CollectionView-Layout spezifizieren. 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 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.Add(image);
grid.Add(nameLabel, 1, 0);
grid.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; }
}
Der folgende Screenshot zeigt das Ergebnis der Erstellung von Vorlagen für die einzelnen Elemente der Liste:
Tipp
Wenn Sie eine CollectionView in einem VerticalStackLayout platzieren, kann dies den CollectionView-Bildlauf stoppen und die Anzahl der angezeigten Elemente begrenzen. Ersetzen Sie in diesem Fall das VerticalStackLayout durch ein Grid.
Weitere Informationen zu Datenvorlagen finden Sie unter 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 OtherMonkey
DataTemplate-Eigenschaften, die auf verschiedene Datenvorlagen festgelegt sind. 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:
Weitere Informationen zu Datenvorlagenselektoren finden Sie unter Erstellen eines DataTemplateSelectors.
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 = Colors.White };
// ...
SwipeView swipeView = new SwipeView();
SwipeItem favoriteSwipeItem = new SwipeItem
{
Text = "Favorite",
IconImageSource = "favorite.png",
BackgroundColor = Colors.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 = Colors.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:
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 über das SwipeView-Steuerelement finden Sie unter 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:
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 zu RefreshView finden Sie unter 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.
Warnung
Versuchen Sie nicht, Daten inkrementell in eine CollectionView zu laden, die sich in einem StackLayout befindet. Dieses Szenario führt zu einer Endlosschleife, in der die CollectionView immer größer wird.
CollectionView definiert die folgenden Eigenschaften zur Steuerung des inkrementellen Ladens von Daten:
RemainingItemsThreshold
, vom Typint
, der Schwellenwert der noch nicht sichtbaren Elemente in der Liste, bei dem das EreignisRemainingItemsThresholdReached
ausgelöst wird.RemainingItemsThresholdReachedCommand
vom Typ ICommand, der ausgeführt wird, wenn derRemainingItemsThreshold
erreicht wird.RemainingItemsThresholdReachedCommandParameter
, vom Typobject
: Parameter, der an denRemainingItemsThresholdReachedCommand
ü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.