Xamarin.Forms CollectionView-Daten
CollectionView
enthält die folgenden Eigenschaften, die die anzuzeigenden Daten und deren Darstellung definieren:
ItemsSource
, vom TypIEnumerable
, gibt die Sammlung der anzuzeigenden Elemente an und hat den Standardwertnull
.ItemTemplate
, vom TypDataTemplate
, 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. Informationen zum Definieren der Darstellung jedes Elements in der CollectionView
finden Sie unter Definieren der Darstellung von Elementen. 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:
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 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 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:
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:
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 RefreshView
finden 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 Typint
, der Schwellenwert der noch nicht sichtbaren Elemente in der Liste, bei dem das EreignisRemainingItemsThresholdReached
ausgelöst wird.RemainingItemsThresholdReachedCommand
vom TypICommand
, 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.