ListView
.NET Multi-platform App UI (.NET MAUI) ListView affiche une liste verticale déroulante d’éléments de données sélectionnables. Alors que ListView gère l’apparence de la liste, DataTemplate définit l’apparence de chaque élément de la liste en utilisant un Cell pour les afficher. .NET MAUI inclut cinq types de cellules pour afficher différentes combinaisons de textes et d’images. Vous pouvez également définir des cellules personnalisées qui affichent le contenu souhaité. ListView prend en charge l’affichage d’éléments d’en-tête et de pied de page, de données groupées, de balayage pour actualiser et de menu contextuel.
La classe ListView est issue de la classe ItemsView<Cell>
, dont elle hérite des propriétés suivantes :
ItemsSource
, de typeIEnumerable
, spécifie la collection d’éléments à afficher et a une valeur par défaut denull
.ItemTemplate
, de type DataTemplate, spécifie le modèle à appliquer à chaque élément de la collection d’éléments à afficher.
ListView définit les propriétés suivantes :
Footer
, de typeobject
, spécifie la chaîne ou la vue qui sera affichée à la fin de la liste.FooterTemplate
, de type DataTemplate, spécifie le DataTemplate à utiliser pour mettre en forme leFooter
.GroupHeaderTemplate
, de type DataTemplate, définit le DataTemplate utilisé pour définir l’apparence de l’en-tête de chaque groupe. Cette propriété s’exclue mutuellement avec la propriétéGroupDisplayBinding
. Par conséquent, la définition de cette propriété configureGroupDisplayBinding
surnull
.HasUnevenRows
, de typebool
, indique si les éléments de la liste peuvent avoir des lignes de hauteurs différentes. La valeur par défaut de cette propriété estfalse
.Header
, de typeobject
, spécifie la chaîne ou la vue qui sera affichée au début de la liste.HeaderTemplate
, de type DataTemplate, spécifie le DataTemplate à utiliser pour mettre en forme leHeader
.HorizontalScrollBarVisibility
, de typeScrollBarVisibility
, indique le moment où la barre de défilement horizontale est visible.IsGroupingEnabled
, de typebool
, indique si les données sous-jacentes doivent être affichées dans des groupes. La valeur par défaut de cette propriété estfalse
.IsPullToRefreshEnabled
, de typebool
, indique si l’utilisateur peut balayer l’écran vers le bas pour que le ListView actualise ses données. La valeur par défaut de cette propriété estfalse
.IsRefreshing
, de typebool
, indique si le ListView est en cours d’actualisation. La valeur par défaut de cette propriété estfalse
.RefreshCommand
, de type ICommand, représente la commande qui s’exécute lorsqu’une actualisation est déclenchée.RefreshControlColor
, de type Color, détermine la couleur de la visualisation d’actualisation qui s’affiche lorsqu’une actualisation se produit.RowHeight
, de typeint
, détermine la hauteur de chaque ligne quandHasUnevenRows
estfalse
.SelectedItem
, de typeobject
, représente l’élément actuellement sélectionné dans le ListView.SelectionMode
, de typeListViewSelectionMode
, indique si vous pouvez sélectionner des éléments dans le ListView. La valeur par défaut de cette propriété estSingle
.SeparatorColor
, de type Color, définit la couleur de la barre qui sépare les éléments de la liste.SeparatorVisibility
, de typeSeparatorVisibility
, définit si des séparateurs sont visibles entre les éléments.VerticalScrollBarVisibility
, de typeScrollBarVisibility
, indique le moment où la barre de défilement verticale est visible.
Toutes ces propriétés s’appuient sur des objets BindableProperty, ce qui signifie qu’elles peuvent être les cibles de liaisons de données et mises en forme avec un style.
En outre, ListView définit les propriétés suivantes qui ne sont pas sauvegardées par les objets BindableProperty :
GroupDisplayBinding
, de typeBindingBase
, définit la liaison à utiliser pour afficher l’en-tête de groupe. Cette propriété s’exclue mutuellement avec la propriétéGroupHeaderTemplate
. Par conséquent, la définition de cette propriété configureGroupHeaderTemplate
surnull
.GroupShortNameBinding
, de typeBindingBase
, définit la liaison du nom à afficher dans les listes de raccourcis groupées.CachingStrategy
, de typeListViewCachingStrategy
, définit la stratégie de réutilisation des cellules du ListView. Il s’agit d’une propriété en lecture seule.
ListView définit les événements suivants :
ItemAppearing
, qui se déclenche lorsque l’utilisateur ajoute la représentation visuelle d’un élément à la disposition visuelle du ListView. L’objetItemVisibilityEventArgs
qui accompagne cet événement définit les propriétésItem
etIndex
.ItemDisappearing
, qui se déclenche lorsque l’utilisateur supprime la représentation visuelle d’un élément de la disposition visuelle du ListView. L’objetItemVisibilityEventArgs
qui accompagne cet événement définit les propriétésItem
etIndex
.ItemSelected
, qui se déclenche lorsque l’utilisateur sélectionne un nouvel élément de la liste. L’objetSelectedItemChangedEventArgs
qui accompagne cet événement définit les propriétésSelectedItem
etSelectedItemIndex
.ItemTapped
, qui se déclenche lorsque l’utilisateur appuie sur un élément du ListView. L’objetItemTappedEventArgs
qui accompagne cet événement définit les propriétésGroup
,Item
etItemIndex
.Refreshing
, qui se déclenche lorsque l’utilisateur lance une opération de balayage pour actualiser sur le ListView.Scrolled
, . L’objetScrolledEventArgs
qui accompagne cet événement définit les propriétésScrollX
etScrollY
.ScrollToRequested
. L’objetScrollToRequestedEventArgs
qui accompagne cet événement définit les propriétés Element,Mode
,Position
,ScrollX
,ScrollY
etShouldAnimate
.
Remplir un ListView avec des données
Vous pouvez remplir un ListView avec des données en définissant sa propriété ItemsSource
sur n’importe quelle collection qui implémente IEnumerable
.
Important
Si ListView 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 ListView 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
:
<ListView ItemsSource="{Binding Monkeys}" />
Le code C# équivalent est :
ListView listView = new ListView();
listView.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
Vous pouvez activer les liaisons compilées pour améliorer les performances de liaison de données dans les applications .NET MAUI. Pour plus d’informations, consultez Liaisons compilées.
Pour plus d’informations sur la liaison de données, consultez Liaison de données.
Définir l’apparence de l’élément
Vous pouvez définir l’apparence de chaque élément dans ListView en définissant la propriété ItemTemplate
sur un DataTemplate :
<ListView ItemsSource="{Binding Monkeys}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<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>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Les éléments spécifiés dans un DataTemplate définissent l’apparence de chaque élément de la liste. Un enfant du DataTemplate doivent être un objet Cell. 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; }
}
La capture d’écran suivante montre le résultat de la modélisation de chaque élément de la liste :
Pour plus d’informations sur les modèles de données, consultez Modèles de données.
Cellules
L’apparence de chaque élément d’un ListView est définie par un DataTemplate. et le DataTemplate doit référencer une classe Cell pour afficher les éléments. Chaque cellule représente un élément de données dans le ListView. .NET MAUI inclut les cellules intégrées suivantes :
- TextCell, qui affiche le texte principal et le texte secondaire sur des lignes distinctes.
- ImageCell, qui affiche une image avec le texte principal et le texte secondaire sur des lignes distinctes.
- SwitchCell, qui affiche du texte et un commutateur pouvant être activé ou désactivé.
- EntryCell, qui affiche une étiquette et un texte modifiable.
- ViewCell, qui est une cellule personnalisée dont l’apparence est définie par View. Vous devez utiliser ce type de cellule si vous souhaitez définir entièrement l’apparence de chaque élément dans ListView.
En général, SwitchCell et EntryCell sont uniquement utilisés dans un TableView et ne sont pas utilisés dans un ListView. Pour en savoir plus sur SwitchCell et EntryCell, consultez TableView.
Cellule de texte
TextCell affiche le texte principal et le texte secondaire sur des lignes distinctes. TextCell définit les propriétés suivantes :
Text
, de typestring
, définit le texte principal à afficher.TextColor
, de type Color, représente la couleur du texte principal.Detail
, de typestring
, définit le texte secondaire à afficher.DetailColor
, de type Color, indique la couleur du texte secondaire.Command
, de type ICommand, définit la commande exécutée quand l’utilisateur appuie sur la cellule.CommandParameter
, de typeobject
, représente le paramètre passé à la commande.
Les propriétés s’appuient sur des objets BindableProperty, ce qui signifie qu’elles peuvent être les cibles de liaisons de données et mises en forme avec un style.
L’exemple suivant montre comment utiliser TextCell pour définir l’apparence d’éléments dans ListView :
<ListView ItemsSource="{Binding Food}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}"
Detail="{Binding Description}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
La capture d’écran suivante montre l’apparence des cellules obtenue :
Cellule d’image
ImageCell affiche une image avec le texte principal et le texte secondaire sur des lignes distinctes. ImageCell hérite des propriétés de TextCell et définit la propriété ImageSource, de type ImageSource, qui spécifie l’image à afficher dans la cellule. Cette propriété s’appuie sur un objet BindableProperty, ce qui signifie qu’elle peut être la cible de liaisons de données et mise en forme avec un style.
L’exemple suivant montre comment utiliser ImageCell pour définir l’apparence d’éléments dans ListView :
<ListView ItemsSource="{Binding Food}">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell ImageSource="{Binding Image}"
Text="{Binding Name}"
Detail="{Binding Description}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
La capture d’écran suivante montre l’apparence des cellules obtenue :
Cellule de vue
ViewCell est une cellule personnalisée dont l’apparence est définie par View. ViewCell définit une propriété View, de type View, qui définit la vue représentant le contenu de la cellule. Cette propriété s’appuie sur un objet BindableProperty, ce qui signifie qu’elle peut être la cible de liaisons de données et mise en forme avec un style.
Remarque
La propriété View est la propriété de contenu de la classe ViewCell et n’a donc pas besoin d’être explicitement définie à partir du code XAML.
L’exemple suivant montre comment utiliser ViewCell pour définir l’apparence d’éléments dans ListView :
<ListView ItemsSource="{Binding Monkeys}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<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>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
À l’intérieur de ViewCell, la disposition peut être gérée par n’importe quelle disposition .NET MAUI. Dans cet exemple, la disposition est gérée par un Grid. Grid contient un objet Image et deux objets Label qui sont tous liés aux propriétés de la classe Monkey
.
La capture d’écran suivante montre le résultat de la modélisation de chaque élément de la liste :
Choisir l’apparence de l’élément au moment de l’exécution
Vous pouvez choisir l’apparence de chaque élément dans ListView au moment de l’exécution, en fonction de la valeur de l’élément, en définissant la propriété ItemTemplate
sur un objet DataTemplateSelector :
<ContentPage ...
xmlns:templates="clr-namespace:ListViewDemos.Templates">
<ContentPage.Resources>
<DataTemplate x:Key="AmericanMonkeyTemplate">
<ViewCell>
...
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="OtherMonkeyTemplate">
<ViewCell>
...
</ViewCell>
</DataTemplate>
<templates:MonkeyDataTemplateSelector x:Key="MonkeySelector"
AmericanMonkey="{StaticResource AmericanMonkeyTemplate}"
OtherMonkey="{StaticResource OtherMonkeyTemplate}" />
</ContentPage.Resources>
<Grid Margin="20">
<ListView ItemsSource="{Binding Monkeys}"
ItemTemplate="{StaticResource MonkeySelector}" />
</Grid>
</ContentPage>
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 DataTemplateSelector.
Répondre à la sélection d’un élément
Par défaut, la sélection ListView est désactivée. Vous pouvez modifier ce comportement en définissant la propriété SelectionMode
. L’énumération ListViewSelectionMode
définit les membres suivants :
None
: indique que l’utilisateur ne peut pas sélectionner d’éléments.Single
: indique que l’utilisateur peut sélectionner un élément unique, l’élément sélectionné étant mis en surbrillance. Il s’agit de la valeur par défaut.
ListView définit un événement ItemSelected
qui se déclenche lorsque la propriété SelectedItem
change, parce qu’un utilisateur sélectionne un élément dans la liste ou parce qu’une application configure la propriété. L’objet SelectedItemChangedEventArgs
qui accompagne cet événement définit les propriétés SelectedItem
et SelectedItemIndex
.
Lorsque la propriété SelectionMode
a la valeur Single
, un seul élément dans le fichier ListView peut être sélectionné. Lorsqu’un élément est sélectionné, la propriété SelectedItem
est définie sur la valeur de l’élément sélectionné. Lorsque cette propriété change, l’événement ItemSelected
se déclenche.
L’exemple suivant montre un ListView qui peut répondre à une sélection d’élément unique :
<ListView ItemsSource="{Binding Monkeys}"
ItemSelected="OnItemSelected">
...
</ListView>
Dans cet exemple, le gestionnaire d’événements OnItemSelected
s’exécute lorsque l’événement ItemSelected
se déclenche et le gestionnaire d’événements récupère l’élément sélectionné :
void OnItemSelected(object sender, SelectedItemChangedEventArgs args)
{
Monkey item = args.SelectedItem as Monkey;
}
La capture d’écran suivante montre la sélection d’un élément unique dans un ListView :
Effacer la sélection
La propriété SelectedItem
peut être effacée en la définissant (ou en définissant l’objet auquel elle est liée) sur null
.
Désactiver la sélection
La sélection ListView est activée par défaut. Cependant, vous pouvez désactiver le défilement en définissant la propriété SelectionMode
sur None
:
<ListView ...
SelectionMode="None" />
Lorsque la propriété SelectionMode
est définie sur None
, les éléments dans le ListView ne peuvent pas être sélectionnés, la propriété SelectedItem
reste null
et l’événement ItemSelected
ne se déclenche pas.
Données de cache
ListView est une vue puissante pour l’affichage des données, mais elle présente certaines limitations. Les performances de défilement peuvent souffrir lors de l’utilisation de cellules personnalisées, en particulier lorsqu’elles contiennent des hiérarchies d’affichage profondément imbriquées ou utilisent certaines dispositions qui nécessitent une mesure complexe. Heureusement, certains techniques vous permettent d’éviter les problèmes de performance.
Un ListView est souvent utilisé pour afficher beaucoup plus de données qu’à l’écran. Par exemple, une application musicale peut avoir une bibliothèque de chansons avec des milliers d’entrées. La création d’un élément pour chaque entrée gaspille une mémoire précieuse et fonctionne mal. La création et la destruction de lignes nécessitent constamment que l’application instancie et nettoie constamment les objets, ce qui fonctionne également mal.
Pour conserver la mémoire, les équivalents ListView natifs de chaque plateforme ont des fonctionnalités intégrées pour réutiliser les lignes. Seules les cellules visibles à l’écran sont chargées en mémoire. Le contenu est chargé dans les cellules existantes. Ce modèle empêche l’application d’instancier des milliers d’objets, afin d’économiser du temps et de la mémoire.
.NET MAUI autorise la réutilisation des cellules ListView au travers de l’énumération ListViewCachingStrategy
, qui définit les membres suivants :
RetainElement
, spécifie que le ListView génère une cellule pour chaque élément de la liste.RecycleElement
, spécifie que le ListView va tenter de réduire son empreinte mémoire et sa vitesse d’exécution en recyclant les cellules de la liste de recyclage.RecycleElementAndDataTemplate
, commeRecycleElement
, garantit que lorsqu’un ListView utilise un DataTemplateSelector, les objets DataTemplate sont mis en cache par le type d’élément de la liste.
Conserver les éléments
La stratégie de mise en cache RetainElement
spécifie que la cellule ListView génère une cellule pour chaque élément de la liste. Il s’agit du comportement par défaut ListView. Il doit être utilisé dans les circonstances suivantes :
- Chaque cellule a un grand nombre de liaisons (de 20 à + de 30).
- Le modèle de cellule change fréquemment.
- Les tests révèlent que la stratégie de mise en cache
RecycleElement
entraîne une vitesse d’exécution réduite.
Il est important de reconnaître les conséquences de la stratégie de mise en cache RetainElement
lors de l’utilisation de cellules personnalisées. Tout code d’initialisation de cellule doit s’exécuter pour chaque création de cellule, qui peut être de plusieurs fois par seconde. Dans ce cas, les techniques de disposition qui étaient correctes sur une page, comme l’utilisation de plusieurs objets imbriqués Grid, deviennent des goulots d’étranglement des performances lorsqu’elles sont configurées et détruites en temps réel lorsque l’utilisateur fait défiler l’écran.
Éléments de recyclage
La stratégie de mise en cache RecycleElement
spécifie que le ListView va tenter de réduire son empreinte mémoire et sa vitesse d’exécution en recyclant les cellules de la liste de recyclage. Ce mode n’offre pas toujours d’amélioration des performances. Vous devez mener des tests pour déterminer les améliorations. Toutefois, il s’agit du choix privilégié, qui doit être utilisé dans les circonstances suivantes :
- Chaque cellule a un petit nombre modéré de liaisons.
- Le
BindingContext
de chaque cellule définit toutes les données de cellule. - Chaque cellule est très similaire, le modèle de cellule étant le même.
Pendant la virtualisation, le contexte de liaison de la cellule est mis à jour. Par conséquent, si une application utilise ce mode, elle doit s’assurer que les mises à jour du contexte de liaison sont correctement gérées. Toutes les données relatives à la cellule doivent provenir du contexte de liaison, sous peine d’erreurs de cohérence. Ce problème peut être évité en utilisant la liaison de données pour afficher les données de cellule. Vous pouvez également définir les données de cellule dans le remplacement OnBindingContextChanged
(plutôt que dans le constructeur de la cellule personnalisée), comme illustré dans l’exemple suivant :
public class CustomCell : ViewCell
{
Image image = null;
public CustomCell()
{
image = new Image();
View = image;
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
var item = BindingContext as ImageItem;
if (item != null)
{
image.Source = item.ImageUrl;
}
}
}
Recycler des éléments avec un DataTemplateSelector
Lorsqu’un ListView utilise un DataTemplateSelector pour sélectionner un DataTemplate, la stratégie de mise en cache RecycleElement
ne met pas en cache les objets DataTemplate. Au lieu de cela, un DataTemplate est sélectionné pour chaque élément de données de la liste.
Remarque
La stratégie de mise en cache RecycleElement
requiert que lorsqu’un DataTemplateSelector est invité à sélectionner un DataTemplate, chaque DataTemplate doit retourner le même type ViewCell. Prenons l’exemple d’un ListView avec un DataTemplateSelector pouvant retourner MyDataTemplateA
(où MyDataTemplateA
retourne un ViewCell de type MyViewCellA
) ou MyDataTemplateB
(où MyDataTemplateB
retourne un ViewCell de type MyViewCellB
), lorsque MyDataTemplateA
est retourné, il doit retourner MyViewCellA
, sous peine de générer une exception.
Recycler des éléments avec un DataTemplates
La stratégie de mise en cache RecycleElementAndDataTemplate
s’appuie sur la stratégie de mise en cache RecycleElement
en s’assurant (en plus) que lorsqu’un ListView utilise un DataTemplateSelector pour sélectionner un DataTemplate, les objets DataTemplate sont mis en cache par le type d’élément de la liste. Par conséquent, les objets DataTemplate sont sélectionnés une fois par type d’élément, au lieu d’une seule fois par instance d’élément.
Remarque
La stratégie de mise en cache RecycleElementAndDataTemplate
nécessite que les objets DataTemplate retournés par le DataTemplateSelector utilisent le constructeur DataTemplate qui prend un Type
.
Définir la stratégie de mise en cache
La stratégie de mise en cache ListView peut être définie en XAML en configurant l’attribut CachingStrategy
:
<ListView CachingStrategy="RecycleElement">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
...
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
En C#, la stratégie de mise en cache est définie au travers d’une surcharge du constructeur :
ListView listView = new ListView(ListViewCachingStrategy.RecycleElement);
Définir la stratégie de mise en cache dans un ListView sous-classé
La définition de l’attribut CachingStrategy
à partir de XAML sur un ListView sous-classé ne produit pas le comportement souhaité, car il n’y a pas de propriété CachingStrategy
sur ListView. La solution à ce problème consiste à spécifier un constructeur sur le ListView sous-classé qui accepte un paramètre ListViewCachingStrategy
et le transmet à la classe de base :
public class CustomListView : ListView
{
public CustomListView (ListViewCachingStrategy strategy) : base (strategy)
{
}
...
}
Ensuite, la valeur d’énumération ListViewCachingStrategy
peut être spécifiée à partir du code XAML avec l’attribut x:Arguments
:
<local:CustomListView>
<x:Arguments>
<ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
</x:Arguments>
</local:CustomListView>
En-têtes et pieds de page
ListView peut présenter un en-tête et un pied de page qui défilent avec les éléments de la liste. L’en-tête et le pied de page peuvent être des chaînes, des vues ou des objets DataTemplate.
ListView définit les propriétés suivantes pour spécifier l’en-tête et le pied de page :
Header
, de typeobject
, spécifie la chaîne, la liaison ou la vue qui sera affichée au début de la liste.HeaderTemplate
, de type DataTemplate, spécifie le DataTemplate à utiliser pour mettre en forme leHeader
.Footer
, de typeobject
, spécifie la chaîne, la liaison ou la vue qui sera affichée à la fin de la liste.FooterTemplate
, de type DataTemplate, spécifie le DataTemplate à utiliser pour mettre en forme leFooter
.
Les propriétés s’appuient sur des objets BindableProperty, ce qui signifie qu’elles peuvent être les cibles de liaisons de données.
Afficher des chaînes dans l’en-tête et le pied de page
Les propriétés Header
et Footer
peuvent être définies sur des valeurs string
, comme illustré dans l’exemple suivant :
<ListView ItemsSource="{Binding Monkeys}"
Header="Monkeys"
Footer="2022">
...
</ListView>
La capture d’écran suivante montre l’en-tête obtenu :
Afficher les vues dans l’en-tête et le pied de page
Les propriétés Header
et Footer
peuvent chacune être définies sur une vue. Il peut s’agir d’une vue unique ou d’une vue contenant plusieurs vues enfants. L’exemple suivant montre les propriétés Header
et Footer
définies sur un objet Grid qui contient un objet Label :
<ListView ItemsSource="{Binding Monkeys}">
<ListView.Header>
<Grid BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Monkeys"
FontSize="12"
FontAttributes="Bold" />
</Grid>
</ListView.Header>
<ListView.Footer>
<Grid BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Friends of Monkey"
FontSize="12"
FontAttributes="Bold" />
</Grid>
</ListView.Footer>
...
</ListView>
La capture d’écran suivante montre l’en-tête obtenu :
Afficher un en-tête et un pied de page avec un modèle
Les propriétés HeaderTemplate
et FooterTemplate
peuvent être définies sur des objets DataTemplate utilisés pour mettre en forme l’en-tête et le pied de page. Dans ce scénario, les propriétés Header
et Footer
doivent être liées à la source actuelle pour que les modèles soient appliqués, comme illustré dans l’exemple suivant :
<ListView ItemsSource="{Binding Monkeys}"
Header="{Binding .}"
Footer="{Binding .}">
<ListView.HeaderTemplate>
<DataTemplate>
<Grid BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Monkeys"
FontSize="12"
FontAttributes="Bold" />
</Grid>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.FooterTemplate>
<DataTemplate>
<Grid BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Friends of Monkey"
FontSize="12"
FontAttributes="Bold" />
</Grid>
</DataTemplate>
</ListView.FooterTemplate>
...
</ListView>
Séparateurs d’éléments de contrôle
Par défaut, des séparateurs s’affichent entre les éléments ListView sur iOS et Android. Ce comportement peut être modifié en définissant la propriété SeparatorVisibility
, de type SeparatorVisibility
, sur None
:
<ListView ...
SeparatorVisibility="None" />
En outre, lorsque le séparateur est activé, sa couleur peut être définie avec la propriété SeparatorColor
:
<ListView ...
SeparatorColor="Blue" />
Dimensionner les éléments
Par défaut, tous les éléments d’un ListView ont la même hauteur, qui est dérivée du contenu du DataTemplate qui définit l’apparence de chaque élément. Toutefois, vous pouvez modifier ce comportement avec les propriétés HasUnevenRows
et RowHeight
. Par défaut, la propriété HasUnevenRows
est false
.
Vous pouvez définir la propriété RowHeight
sur un int
qui représente la hauteur de chaque élément de ListView, à condition que HasUnevenRows
soit false
. Quand HasUnevenRows
est défini sur true
, chaque élément de ListView peut avoir une hauteur différente. La hauteur de chaque élément étant dérivée du contenu de l’élément DataTemplate, chaque élément est dimensionné en fonction de son contenu.
Vous pouvez redimensionner par programmation des éléments ListView individuels au moment de l’exécution en modifiant les propriétés liées à la disposition des éléments de DataTemplate, à condition que la propriété HasUnevenRows
soit true
. L’exemple suivant modifie la hauteur d’un objet Image quand l’utilisateur appuie dessus :
void OnImageTapped(object sender, EventArgs args)
{
Image image = sender as Image;
ViewCell viewCell = image.Parent.Parent as ViewCell;
if (image.HeightRequest < 250)
{
image.HeightRequest = image.Height + 100;
viewCell.ForceUpdateSize();
}
}
Dans cet exemple, le gestionnaire d’événements OnImageTapped
est exécuté quand l’utilisateur appuie sur un objet Image. Le gestionnaire d’événements met à jour la hauteur du Image et la méthode Cell.ForceUpdateSize
met à jour la taille de la cellule, même lorsqu’elle n’est pas visible.
Avertissement
L’utilisation excessive du dimensionnement dynamique des éléments peut entraîner une dégradation des performances de ListView.
Disposition de droite à gauche
Pour que ListView applique à son contenu une direction de flux de droite à gauche, définissez sa propriété FlowDirection
sur RightToLeft
. Cependant, la propriété FlowDirection
doit idéalement être définie sur une page ou une disposition racine. Ainsi, tous les éléments de la page ou de la disposition racine répondent à la direction de flux :
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ListViewDemos.RightToLeftListPage"
Title="Right to left list"
FlowDirection="RightToLeft">
<Grid Margin="20">
<ListView ItemsSource="{Binding Monkeys}">
...
</ListView>
</Grid>
</ContentPage>
La valeur par défaut de FlowDirection
pour un élément avec un parent est MatchParent
. Par conséquent, le ListView hérite de la valeur de la propriété FlowDirection
de Grid, qui hérite à son tour de la valeur de la propriété FlowDirection
de ContentPage.
Afficher les données groupées
Les jeux de données volumineux sont souvent difficiles à gérer lorsqu’ils sont présentés dans une liste de défilement continue. Dans ce scénario, l’organisation des données en groupes peut améliorer l’expérience utilisateur en facilitant la navigation dans les données.
Les données doivent être regroupées avant de pouvoir être affichées. Pour ce faire, créez une liste de groupes, où chaque groupe est une liste d’éléments. La liste des groupes doit être une collection IEnumerable<T>
, où T
définit deux éléments de données :
- Un nom de groupe.
- Une collection
IEnumerable
qui définit les éléments appartenant au groupe.
Le processus de regroupement des données consiste donc à :
- Créer un type qui modélise un élément unique.
- Créez un type qui modélise un groupe d’éléments unique.
- Créez une collection
IEnumerable<T>
, oùT
est le type qui modélise un groupe d’éléments unique. Cette collection est une collection de groupes qui stocke les données groupées. - Ajouter des données à la collection
IEnumerable<T>
.
Exemple
Lors du regroupement de données, la première étape consiste à créer un type qui modélise un élément unique. L’exemple suivant présente la classe Animal
:
public class Animal
{
public string Name { get; set; }
public string Location { get; set; }
public string Details { get; set; }
public string ImageUrl { get; set; }
}
La classe Animal
modélise un élément unique. Un type qui modélise un groupe d’éléments peut ensuite être créé. L’exemple suivant présente la classe AnimalGroup
:
public class AnimalGroup : List<Animal>
{
public string Name { get; private set; }
public AnimalGroup(string name, List<Animal> animals) : base(animals)
{
Name = name;
}
}
La classe AnimalGroup
hérite de la classe List<T>
et ajoute une propriété Name
qui représente le nom du groupe.
Une collection de groupes IEnumerable<T>
peut ensuite être créée :
public List<AnimalGroup> Animals { get; private set; } = new List<AnimalGroup>();
Ce code définit une collection nommée Animals
, où chaque élément de la collection est un objet AnimalGroup
. Chaque objet AnimalGroup
comprend un nom et une collection List<Animal>
qui définit les objets Animal
du groupe.
Les données groupées peuvent ensuite être ajoutées à la collection Animals
:
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"
},
// ...
}));
Ce code crée deux groupes dans la collection Animals
. Le premier AnimalGroup
est nommé Bears
et contient une collection List<Animal>
de détails « Bear ». Le second AnimalGroup
est nommé Monkeys
, et contient une List<Animal>
collection de détails « Monkey ».
ListView affiche les données groupées, à condition que les données aient été correctement regroupées, en définissant la propriété IsGroupingEnabled
sur true
:
<ListView ItemsSource="{Binding Animals}"
IsGroupingEnabled="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<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>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Le code C# équivalent est :
ListView listView = new ListView
{
IsGroupingEnabled = true
};
listView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
// ...
Vous pouvez définir l’apparence de chaque élément dans ListView en définissant la propriété ItemTemplate
sur un DataTemplate. Pour plus d’informations, consultez Définir l’apparence d’un élément.
La capture d’écran suivante montre le ListView affichant les données groupées :
Remarque
Par défaut, ListView affiche le nom du groupe dans l’en-tête du groupe. Vous pouvez modifier ce comportement en personnalisant l’en-tête de groupe.
Personnaliser l’en-tête de groupe
Vous pouvez définir l’apparence de chaque élément en définissant la propriété ListView.GroupHeaderTemplate
sur un DataTemplate :
<ListView ItemsSource="{Binding Animals}"
IsGroupingEnabled="True">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding Name}"
BackgroundColor="LightGray"
FontSize="18"
FontAttributes="Bold" />
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
...
</ListView>
Dans cet exemple, chaque en-tête de groupe est défini sur un Label qui affiche le nom de groupe et qui a d’autres propriétés d’apparence définies. La capture d’écran suivante montre l’en-tête de groupe personnalisée :
Important
La propriété GroupHeaderTemplate
s’exclue mutuellement avec la propriété GroupDisplayBinding
. Par conséquent, les deux propriétés ne doivent pas être définies.
Grouper sans modèles
ListView peut afficher correctement les données regroupées sans définir la propriété ItemTemplate
sur un DataTemplate :
<ListView ItemsSource="{Binding Animals}"
IsGroupingEnabled="true" />
Dans ce scénario, des données significatives peuvent être affichées en remplaçant la méthode ToString
dans le type qui modélise un élément unique et le type qui modélise un groupe d’éléments unique.
Contrôler le défilement
ListView définit deux méthodes ScrollTo
, qui font défiler les éléments dans l’affichage. L’une des surcharges fait défiler l’élément spécifié dans la vue, tandis que l’autre fait défiler l’élément spécifié dans le groupe spécifié dans la vue. Les deux surcharges ont des arguments supplémentaires qui permettent la position exacte de l’élément une fois le défilement terminé, lorsqu’il faut animer le défilement.
ListView définit un événement ScrollToRequested
déclenché lorsqu’une des méthodes ScrollTo
est appelée. L’objet ScrollToRequestedEventArgs
qui accompagne l’événement ScrollToRequested
a de nombreuses propriétés, notamment ShouldAnimate
, Element, Mode
, et Position
. Ces propriétés sont définies à partir des arguments spécifiés dans les appels de méthode ScrollTo
.
En outre, ListView définit un événement Scrolled
déclenché pour indiquer que le défilement s’est produit. L’objet ScrolledEventArgs
qui accompagne l’événement Scrolled
définit les propriétés ScrollX
et ScrollY
.
Détecter le défilement
ListView définit un événement Scrolled
qui se déclenche pour indiquer que le défilement s’est produit. La classe ItemsViewScrolledEventArgs
qui représente l’objet qui accompagne l’événement Scrolled
définit les propriétés suivantes :
ScrollX
, de typedouble
, représente la position X du défilementScrollY
, de typedouble
, représente la position Y du défilement.
L’exemple de XAML suivant montre un ListView qui définit un gestionnaire d’événements pour l’événement Scrolled
:
<ListView Scrolled="OnListViewScrolled">
...
</ListView>
Le code C# équivalent est :
ListView listView = new ListView();
listView.Scrolled += OnListViewScrolled;
Dans cet exemple, le gestionnaire d’événements OnListViewScrolled
s’exécute lorsque l’événement Scrolled
se déclenche :
void OnListViewScrolled(object sender, ScrolledEventArgs e)
{
// Custom logic
}
Important
L’événement Scrolled
se déclenche pour les défilements initiés par l’utilisateur et les défilements programmatiques.
Faire défiler un élément dans la vue
La méthode ScrollTo
fait défiler l’élément spécifié dans la vue. Pour un objet ListView nommé listView
, l’exemple suivant montre comment faire défiler l’élément Proboscis Monkey dans la vue :
MonkeysViewModel viewModel = BindingContext as MonkeysViewModel;
Monkey monkey = viewModel.Monkeys.FirstOrDefault(m => m.Name == "Proboscis Monkey");
listView.ScrollTo(monkey, ScrollToPosition.MakeVisible, true);
Vous pouvez également faire défiler un élément dans les données groupées dans la vue en spécifiant l’élément et le groupe. L’exemple suivant montre comment faire défiler l’élément Proboscis Monkey du groupe Monkeys dans la vue :
GroupedAnimalsViewModel viewModel = BindingContext as GroupedAnimalsViewModel;
AnimalGroup group = viewModel.Animals.FirstOrDefault(a => a.Name == "Monkeys");
Animal monkey = group.FirstOrDefault(m => m.Name == "Proboscis Monkey");
listView.ScrollTo(monkey, group, ScrollToPosition.MakeVisible, true);
Remarque
L’événement ScrollToRequested
se déclenche lorsque la méthode ScrollTo
est appelée.
Désactiver l’animation de défilement
Une animation de défilement s’affiche lors du défilement d’un élément dans la vue. Toutefois, cette animation peut être désactivée en définissant l’argument animated
de la méthode ScrollTo
sur false
:
listView.ScrollTo(monkey, position: ScrollToPosition.MakeVisible, animate: false);
Contrôler la position de défilement
Lors du défilement d’un élément dans la vue, la position exacte de l’élément une fois le défilement terminé peut être définie avec l’argument position
de la méthode ScrollTo
. Cet argument accepte un membre d’énumération ScrollToPosition
.
MakeVisible
Le membre ScrollToPosition.MakeVisible
indique que l’élément doit faire l’objet d’un défilement jusqu’à ce qu’il soit visible dans la vue :
listView.ScrollTo(monkey, position: ScrollToPosition.MakeVisible, animate: true);
Démarrer
Le membre ScrollToPosition.Start
indique que l’élément doit être faire l’objet d’un défilement jusqu’au début de la vue :
listView.ScrollTo(monkey, position: ScrollToPosition.Start, animate: true);
Centrer
Le membre ScrollToPosition.Center
indique que l’élément doit être faire l’objet d’un défilement jusqu’au centre de la vue :
listView.ScrollTo(monkey, position: ScrollToPosition.Center, animate: true);
Fin
Le membre ScrollToPosition.End
indique que l’élément doit être faire l’objet d’un défilement jusqu’à la fin de la vue :
listView.ScrollTo(monkey, position: ScrollToPosition.End, animate: true);
Visibilité de la barre de défilement
ListView définit les propriétés HorizontalScrollBarVisibility
et VerticalScrollBarVisibility
qui s’appuient sur des propriétés pouvant être liées. Ces propriétés obtiennent ou définissent une valeur d’énumération ScrollBarVisibility
qui indique si la barre de défilement horizontale ou verticale est visible. L’énumération ScrollBarVisibility
définit les membres suivants :
Default
indique le comportement de la barre de défilement par défaut pour la plateforme et constitue la valeur par défaut des propriétésHorizontalScrollBarVisibility
etVerticalScrollBarVisibility
.Always
indique que la barre de défilement est visible même si le contenu correspond à l’affichage.Never
indique que la barre de défilement n’est pas visible même si le contenu ne correspond pas à l’affichage.
Ajouter des menus contextuels
ListView prend en charge les éléments de menus contextuels, qui sont définis en tant qu’objets MenuItem ajoutés à la collection ViewCell.ContextActions
dans le DataTemplate pour chaque élément :
<ListView x:Name="listView"
ItemsSource="{Binding Monkeys}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Favorite"
Command="{Binding Source={x:Reference listView}, Path=BindingContext.FavoriteCommand}"
CommandParameter="{Binding}" />
<MenuItem Text="Delete"
Command="{Binding Source={x:Reference listView}, Path=BindingContext.DeleteCommand}"
CommandParameter="{Binding}" />
</ViewCell.ContextActions>
...
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Les objets MenuItem sont révélés lorsque l’utilisateur clique sur un élément du ListView avec le bouton droit :
Pour plus d’informations sur les éléments de menu, consultez Afficher les éléments de menu.
Tirer pour actualiser
ListView prend en charge la fonctionnalité de balayage pour actualiser, ce qui permet d’actualiser les données affichées en balayant la liste d’éléments vers le bas.
Pour activer le balayage pour actualiser, définissez la propriété IsPullToRefreshEnabled
sur true
. Lorsqu’une actualisation est déclenchée, ListView déclenche l’événement Refreshing
et la propriété IsRefreshing
est définie sur true
. Le code requis pour actualiser le contenu du ListView doit ensuite être exécuté par le gestionnaire pour l’événement Refreshing
, ou par l’implémentation ICommand que RefreshCommand
exécute. Une fois ListView actualisé, la propriété IsRefreshing
doit être définie sur false
, ou la méthode EndRefresh
doit être appelée sur le ListView pour indiquer que l’actualisation est terminée.
L’exemple suivant montre un ListView qui utiliser le balayage pour actualiser :
<ListView ItemsSource="{Binding Animals}"
IsPullToRefreshEnabled="true"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
...
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Dans cet exemple, lorsque l’utilisateur lance une actualisation, le ICommand défini par la propriété RefreshCommand
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é IsRefreshing
indique l’état actuel d’opération d’actualisation. Quand une actualisation est déclenchée, cette propriété passe automatiquement à true
. Une fois l’actualisation terminée, vous devez rétablir la valeur false
de la propriété.