Xamarin.Forms Données CollectionView
CollectionView
inclut les propriétés suivantes qui définissent les données à afficher et son apparence :
ItemsSource
, de typeIEnumerable
, spécifie la collection d’éléments à afficher et a une valeur par défaut denull
.ItemTemplate
, de typeDataTemplate
, spécifie le modèle à appliquer à chaque élément de la collection d’éléments à afficher.
Les propriétés s’appuient sur des objets BindableProperty
, ce qui signifie qu’elles peuvent être les cibles de liaisons de données.
Remarque
CollectionView
définit une propriété ItemsUpdatingScrollMode
qui représente le comportement de défilement de CollectionView
lorsque de nouveaux éléments y sont ajoutés. Pour plus d’informations sur cette propriété, consultez Contrôler la position de défilement lorsque de nouveaux éléments sont ajoutés.
CollectionView
prend en charge la virtualisation incrémentielle des données à mesure que l’utilisateur réalise un défilement. Pour plus d’informations, consultez Charger des données de manière incrémentielle.
Remplir un CollectionView avec des données
Vous pouvez remplir un CollectionView
avec des données en définissant sa propriété ItemsSource
sur n’importe quelle collection qui implémente IEnumerable
. Par défaut, CollectionView
affiche les éléments dans une liste verticale.
Important
Si CollectionView
doit être actualisé à mesure que des éléments sont ajoutés, supprimés ou modifiés dans la collection sous-jacente, cette dernière doit être une collection IEnumerable
qui envoie des notifications de modification de propriété, par exemple ObservableCollection
.
Vous pouvez remplir CollectionView
avec des données en utilisant une liaison de données pour lier sa propriété ItemsSource
à une collection IEnumerable
. En XAML, utilisez pour ce faire l’extension de balisage Binding
:
<CollectionView ItemsSource="{Binding Monkeys}" />
Le code C# équivalent est :
CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
Dans cet exemple, les données de la propriété ItemsSource
sont liées à la propriété Monkeys
du viewmodel connecté.
Remarque
Les liaisons compilées peuvent être activées pour améliorer les performances de liaison de données dans les Xamarin.Forms applications. Pour plus d’informations, consultez Liaisons compilées.
Pour plus d’informations sur la modification de la CollectionView
disposition, consultez Xamarin.Forms CollectionView Layout. Pour plus d’informations sur la définition de l’apparence de chaque élément dans CollectionView
, consultez Définir l’apparence d’un élément. Pour plus d’informations sur la liaison de données, consultez Xamarin.Forms Liaison de données.
Avertissement
CollectionView
lève une exception si son ItemsSource
est mis à jour à partir du thread d’interface utilisateur.
Définir l’apparence de l’élément
Vous pouvez définir l’apparence de chaque élément dans CollectionView
en définissant la propriété CollectionView.ItemTemplate
sur un DataTemplate
:
<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>
Le code C# équivalent est :
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;
});
Les éléments spécifiés dans DataTemplate
définissent l’apparence de chaque élément de la liste. Dans l’exemple, la disposition dans DataTemplate
est gérée par Grid
. Grid
contient un objet Image
et deux objets Label
qui sont tous liés aux propriétés de la classe Monkey
:
public class Monkey
{
public string Name { get; set; }
public string Location { get; set; }
public string Details { get; set; }
public string ImageUrl { get; set; }
}
Les captures d’écran suivantes montrent le résultat de la création de modèles pour chaque élément de la liste :
Pour plus d’informations sur les modèles de données, consultez Xamarin.Forms Modèles de données.
Choisir l’apparence de l’élément au moment de l’exécution
Vous pouvez choisir l’apparence de chaque élément dans CollectionView
au moment de l’exécution, en fonction de la valeur de l’élément, en définissant la propriété CollectionView.ItemTemplate
sur un objet DataTemplateSelector
:
<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>
Le code C# équivalent est :
CollectionView collectionView = new CollectionView
{
ItemTemplate = new MonkeyDataTemplateSelector { ... }
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
La propriété ItemTemplate
est définie sur un objet MonkeyDataTemplateSelector
. L’exemple suivant présente la classe 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;
}
}
La classe MonkeyDataTemplateSelector
définit les propriétés AmericanMonkey
et OtherMonkey
DataTemplate
, qui sont configurées sur différents modèles de données. Le remplacement OnSelectTemplate
retourne le modèle AmericanMonkey
, qui affiche le nom et l’emplacement du singe en bleu-vert lorsque le nom du singe contient « America ». Si le nom du singe ne contient pas « America », le remplacement OnSelectTemplate
retourne le modèle OtherMonkey
, qui affiche le nom et l’emplacement du singe en gris argenté :
Pour plus d’informations sur les sélecteurs de modèles de données, consultez Créer un Xamarin.Forms DataTemplateSelector.
Important
Lorsque vous utilisez CollectionView
, ne définissez jamais l’élément racine de vos objets DataTemplate
sur ViewCell
. Il en résulte la levée d’une exception, car CollectionView
n’a aucun concept des cellules.
Menu contextuels
CollectionView
prend en charge les menus contextuels pour les éléments de données via SwipeView
, qui révèle le menu contextuel avec un mouvement de balayage. SwipeView
est un contrôle conteneur qui enveloppe un élément de contenu et fournit des éléments de menu contextuel pour cet élément de contenu. Les menus contextuels sont donc implémentés pour CollectionView
en créant un SwipeView
qui définit le contenu autour duquel SwipeView
est enveloppé et les éléments de menu contextuel révélés par le mouvement de balayage. Pour ce faire, définissez SwipeView
comme vue racine dans le DataTemplate
qui définit l’apparence de chaque élément de données dans CollectionView
:
<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>
Le code C# équivalent est :
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;
});
Dans cet exemple, le contenu SwipeView
est un Grid
qui définit l’apparence de chaque élément dans CollectionView
. Les éléments de balayage sont utilisés pour effectuer des actions sur le contenu SwipeView
et sont révélés lorsque l’utilisateur balaie le contrôle à partir du côté gauche :
SwipeView
prend en charge quatre directions de balayage différentes, la direction de balayage étant définie par la collection SwipeItems
directionnelle à laquelle les objets SwipeItems
sont ajoutés. Par défaut, un élément de balayage est exécuté lorsque l’utilisateur appuie dessus. En outre, une fois qu’un élément de balayage a été exécuté, les éléments de balayage sont masqués et le contenu SwipeView
est réaffiché. Toutefois, il est possible de modifier ces comportements.
Pour plus d’informations sur le SwipeView
contrôle, consultez Xamarin.Forms SwipeView.
Tirer pour actualiser
CollectionView
prend en charge la fonctionnalité « tirer pour actualiser » via RefreshView
, ce qui permet d’actualiser les données affichées en tirant la liste d’éléments vers le bas. RefreshView
est un contrôle conteneur qui fournit une fonctionnalité « tirer pour actualiser » à son enfant, à condition que ce dernier prenne en charge le contenu avec défilement. La fonctionnalité « tirer pour actualiser » est donc implémentée pour CollectionView
en le définissant comme enfant de RefreshView
:
<RefreshView IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}">
<CollectionView ItemsSource="{Binding Animals}">
...
</CollectionView>
</RefreshView>
Le code C# équivalent est :
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;
// ...
Lorsque l’utilisateur lance une actualisation, le ICommand
défini par la propriété Command
est exécuté, ce qui doit actualiser les éléments affichés. Une visualisation d’actualisation, qui se compose d’un cercle de progression animé, s’affiche pendant l’actualisation :
La valeur de la propriété RefreshView.IsRefreshing
indique l’état actuel de RefreshView
. Quand une actualisation est déclenchée par l’utilisateur, cette propriété passe automatiquement à true
. Une fois l’actualisation terminée, vous devez rétablir la valeur false
de la propriété.
Pour plus d’informations sur RefreshView
, consultez Xamarin.Forms RefreshView.
Charger des données de manière incrémentielle
CollectionView
prend en charge la virtualisation incrémentielle des données à mesure que l’utilisateur réalise un défilement. Cela permet des scénarios tels que le chargement asynchrone d’une page de données à partir d’un service web, à mesure que l’utilisateur fait défiler la page. En outre, vous pouvez configurer le moment auquel plus de données sont chargées pour que les utilisateurs ne voient pas d’espace vide ou ne soient pas empêchés de faire défiler la page.
CollectionView
définit les propriétés suivantes pour contrôler le chargement incrémentiel des données :
RemainingItemsThreshold
, de typeint
, qui correspond au seuil d’éléments non encore visibles dans la liste auquel l’événementRemainingItemsThresholdReached
est déclenché.RemainingItemsThresholdReachedCommand
, de typeICommand
, qui est exécuté lorsqueRemainingItemsThreshold
est atteint.RemainingItemsThresholdReachedCommandParameter
, de typeobject
: paramètre passé à la commandeRemainingItemsThresholdReachedCommand
.
CollectionView
définit également un événement RemainingItemsThresholdReached
qui est déclenché lorsque le CollectionView
fait l’objet d’un défilement suffisamment important pour que les éléments RemainingItemsThreshold
ne soient pas affichés. Cet événement peut être géré pour charger plus d’éléments. En outre, lorsque l’événement RemainingItemsThresholdReached
est déclenché, RemainingItemsThresholdReachedCommand
est exécuté, ce qui permet le chargement incrémentiel des données dans un viewmodel.
La valeur par défaut de la propriété RemainingItemsThreshold
est –1, ce qui indique que l’événement RemainingItemsThresholdReached
n’est jamais déclenché. Lorsque la valeur de la propriété est 0, l’événement RemainingItemsThresholdReached
est déclenché lorsque l’élément final de ItemsSource
est affiché. Pour les valeurs supérieures à 0, l’événement RemainingItemsThresholdReached
est déclenché lorsque ItemsSource
contient le nombre d’éléments qui n’ont pas encore été atteints par défilement.
Remarque
CollectionView
valide la propriété RemainingItemsThreshold
pour que sa valeur soit toujours supérieure ou égale à –1.
L’exemple XAML suivant montre un CollectionView
qui charge les données de manière incrémentielle :
<CollectionView ItemsSource="{Binding Animals}"
RemainingItemsThreshold="5"
RemainingItemsThresholdReached="OnCollectionViewRemainingItemsThresholdReached">
...
</CollectionView>
Le code C# équivalent est :
CollectionView collectionView = new CollectionView
{
RemainingItemsThreshold = 5
};
collectionView.RemainingItemsThresholdReached += OnCollectionViewRemainingItemsThresholdReached;
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
Dans cet exemple de code, l’événement RemainingItemsThresholdReached
se déclenche lorsque 5 éléments n’ont pas encore été atteints par défilement et, en réponse, exécute le gestionnaire d’événements OnCollectionViewRemainingItemsThresholdReached
:
void OnCollectionViewRemainingItemsThresholdReached(object sender, EventArgs e)
{
// Retrieve more data here and add it to the CollectionView's ItemsSource collection.
}
Remarque
Vous pouvez également charger des données de manière incrémentielle en liant RemainingItemsThresholdReachedCommand
à une implémentation ICommand
dans le viewmodel.