Partager via


Spécifier la disposition de CollectionView

Parcourez l’exemple. Parcourir l'exemple

L’interface utilisateur de l’application multiplateforme .NET (.NET MAUI) CollectionView définit les propriétés suivantes qui contrôlent la disposition :

  • ItemsLayout, de type IItemsLayout, spécifie la disposition à utiliser.
  • ItemSizingStrategy, de type ItemSizingStrategy, spécifie la stratégie de mesure d’élément à utiliser.

Les propriétés s’appuient sur des objets BindableProperty, ce qui signifie qu’elles peuvent être les cibles de liaisons de données.

Par défaut, un CollectionView affiche ses éléments dans une liste verticale. Toutefois, l’une des dispositions suivantes peut être utilisée :

  • Liste verticale : une liste à une seule colonne qui se développe verticalement à mesure que de nouveaux éléments sont ajoutés.
  • Liste horizontale : une liste à une seule ligne qui se développe horizontalement à mesure que de nouveaux éléments sont ajoutés.
  • Grille verticale : une grille à plusieurs colonnes qui se développe verticalement à mesure que de nouveaux éléments sont ajoutés.
  • Grille horizontale : une grille à plusieurs lignes qui se développe horizontalement à mesure que de nouveaux éléments sont ajoutés.

Ces dispositions peuvent être spécifiées en définissant la propriété ItemsLayout sur la classe dérivée de la classe ItemsLayout. Cette classe définit les propriétés suivantes :

  • Orientation, de type ItemsLayoutOrientation, spécifie la direction dans laquelle le CollectionView se développe à mesure que les éléments sont ajoutés.
  • SnapPointsAlignment, de type SnapPointsAlignment, spécifie comment les points d’ancrage sont alignés avec les éléments.
  • SnapPointsType, de type SnapPointsType, spécifie le comportement des points d’ancrage lors du défilement.

Les propriétés s’appuient sur des objets BindableProperty, ce qui signifie qu’elles peuvent être les cibles de liaisons de données. Pour plus d’informations sur les points d’ancrage, consultez Points d’ancrage dans le guide Contrôler le défilement dans un CollectionView.

L’énumération ItemsLayoutOrientation définit les membres suivants :

  • Vertical indique que le CollectionView s’étend verticalement à mesure que les éléments sont ajoutés.
  • Horizontal indique que le CollectionView s’étend horizontalement à mesure que les éléments sont ajoutés.

La classe LinearItemsLayout hérite de la classe ItemsLayout et définit une propriété ItemSpacing, de type double, qui représente l’espace vide autour de chaque élément. La valeur par défaut de cette propriété est 0 et sa valeur doit toujours être supérieure ou égale à 0. La classe LinearItemsLayout définit également des membres statiques Vertical et Horizontal. Ces membres peuvent être utilisés pour créer des listes verticales ou horizontales, respectivement. Vous pouvez également créer un objet LinearItemsLayout, en spécifiant un membre d’énumération ItemsLayoutOrientation en tant qu’argument.

La classe GridItemsLayout hérite de la classe ItemsLayout et définit les propriétés suivantes :

  • VerticalItemSpacing, de type double, qui représente l’espace vertical vide autour de chaque élément. La valeur par défaut de cette propriété est 0 et sa valeur doit toujours être supérieure ou égale à 0.
  • HorizontalItemSpacing, de type double, qui représente l’espace horizontal vide autour de chaque élément. La valeur par défaut de cette propriété est 0 et sa valeur doit toujours être supérieure ou égale à 0.
  • Span, de type int, qui représente le nombre de colonnes ou de lignes à afficher dans la grille. La valeur par défaut de cette propriété est 1 et sa valeur doit toujours être supérieure ou égale à 1.

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 utilise les moteurs de disposition natifs pour effectuer la disposition.

Liste verticale

Par défaut, CollectionView affiche ses éléments dans une disposition en liste verticale. Par conséquent, il n’est pas nécessaire de définir la propriété ItemsLayout pour utiliser cette disposition :

<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>

Toutefois,pour être complet, en XAML, un élément CollectionView peut être défini pour afficher ses éléments dans une liste verticale en définissant sa propriété ItemsLayout sur VerticalList :

<CollectionView ItemsSource="{Binding Monkeys}"
                ItemsLayout="VerticalList">
    ...
</CollectionView>

Vous pouvez également effectuer ceci en définissant la propriété ItemsLayout sur un objet LinearItemsLayout, en spécifiant le membre d’énumération Vertical ItemsLayoutOrientation comme valeur de propriété Orientation :

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Le code C# équivalent est :

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = LinearItemsLayout.Vertical
};

Cela donne une liste à une seule colonne, qui se développe verticalement à mesure que de nouveaux éléments sont ajoutés :

Capture d'écran de la disposition en liste verticale CollectionView.

Conseil

Le fait de placer CollectionView à l’intérieur de VerticalStackLayout peut arrêter le défilement de CollectionView et limiter le nombre d’éléments affichés. Dans cette situation, remplacez VerticalStackLayout par Grid.

Liste horizontale

En XAML, un CollectionView peut afficher ses éléments dans une liste horizontale en définissant sa propriété ItemsLayout sur HorizontalList :

<CollectionView ItemsSource="{Binding Monkeys}"
                ItemsLayout="HorizontalList">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="35" />
                    <RowDefinition Height="35" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="70" />
                    <ColumnDefinition Width="140" />
                </Grid.ColumnDefinitions>
                <Image Grid.RowSpan="2"
                       Source="{Binding ImageUrl}"
                       Aspect="AspectFill"
                       HeightRequest="60"
                       WidthRequest="60" />
                <Label Grid.Column="1"
                       Text="{Binding Name}"
                       FontAttributes="Bold"
                       LineBreakMode="TailTruncation" />
                <Label Grid.Row="1"
                       Grid.Column="1"
                       Text="{Binding Location}"
                       LineBreakMode="TailTruncation"
                       FontAttributes="Italic"
                       VerticalOptions="End" />
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Vous pouvez également effectuer cette disposition en définissant la propriété ItemsLayout sur un objet LinearItemsLayout, en spécifiant le membre d’énumération Horizontal ItemsLayoutOrientation comme valeur de propriété Orientation :

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Horizontal" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Le code C# équivalent est :

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = LinearItemsLayout.Horizontal
};

Cela donne une liste à une seule ligne, qui se développe horizontalement à mesure que de nouveaux éléments sont ajoutés :

Capture d'écran de la disposition en liste horizontale CollectionView.

Grille verticale

En XAML, un CollectionView peut afficher ses éléments dans une grille verticale en définissant sa propriété ItemsLayout sur VerticalGrid :

<CollectionView ItemsSource="{Binding Monkeys}"
                ItemsLayout="VerticalGrid, 2">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="35" />
                    <RowDefinition Height="35" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="70" />
                    <ColumnDefinition Width="80" />
                </Grid.ColumnDefinitions>
                <Image Grid.RowSpan="2"
                       Source="{Binding ImageUrl}"
                       Aspect="AspectFill"
                       HeightRequest="60"
                       WidthRequest="60" />
                <Label Grid.Column="1"
                       Text="{Binding Name}"
                       FontAttributes="Bold"
                       LineBreakMode="TailTruncation" />
                <Label Grid.Row="1"
                       Grid.Column="1"
                       Text="{Binding Location}"
                       LineBreakMode="TailTruncation"
                       FontAttributes="Italic"
                       VerticalOptions="End" />
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Cette disposition peut également être réalisée en définissant la propriété ItemsLayout sur un objet GridItemsLayout dont la propriété Orientation est définie sur Vertical :

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
       <GridItemsLayout Orientation="Vertical"
                        Span="2" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Le code C# équivalent est :

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
};

Par défaut, un GridItemsLayout vertical affiche les éléments en une seule colonne. Toutefois, cet exemple définit la propriété GridItemsLayout.Span sur 2. Cela donne une grille à deux colonnes, qui se développe verticalement à mesure que de nouveaux éléments sont ajoutés :

Capture d'écran de la disposition en grille verticale CollectionView.

Grille horizontale

En XAML, un CollectionView peut afficher ses éléments dans une grille horizontale en définissant sa propriété ItemsLayout sur HorizontalGrid :

<CollectionView ItemsSource="{Binding Monkeys}"
                ItemsLayout="HorizontalGrid, 4">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="35" />
                    <RowDefinition Height="35" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="70" />
                    <ColumnDefinition Width="140" />
                </Grid.ColumnDefinitions>
                <Image Grid.RowSpan="2"
                       Source="{Binding ImageUrl}"
                       Aspect="AspectFill"
                       HeightRequest="60"
                       WidthRequest="60" />
                <Label Grid.Column="1"
                       Text="{Binding Name}"
                       FontAttributes="Bold"
                       LineBreakMode="TailTruncation" />
                <Label Grid.Row="1"
                       Grid.Column="1"
                       Text="{Binding Location}"
                       LineBreakMode="TailTruncation"
                       FontAttributes="Italic"
                       VerticalOptions="End" />
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Cette disposition peut également être réalisée en définissant la propriété ItemsLayout sur un objet GridItemsLayout dont la propriété Orientation est définie sur Horizontal :

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
       <GridItemsLayout Orientation="Horizontal"
                        Span="4" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Le code C# équivalent est :

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = new GridItemsLayout(4, ItemsLayoutOrientation.Horizontal)
};

Par défaut, un GridItemsLayout horizontal affiche les éléments en une seule ligne. Toutefois, cet exemple définit la propriété GridItemsLayout.Span sur 4. Cela donne une grille à quatre lignes, qui se développe horizontalement à mesure que de nouveaux éléments sont ajoutés :

Capture d'écran de la disposition en grille horizontale CollectionView.

En-têtes et pieds de page

CollectionView 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.

CollectionView définit les propriétés suivantes pour spécifier l’en-tête et le pied de page :

  • Header, de type object, 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 le Header.
  • Footer, de type object, 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 le Footer.

Les propriétés s’appuient sur des objets BindableProperty, ce qui signifie qu’elles peuvent être les cibles de liaisons de données.

Lorsqu'un en-tête est ajouté à une disposition qui se développe horizontalement, de gauche à droite, l'en-tête est affiché à gauche de la liste. De même, lorsqu'un pied de page est ajouté à une disposition qui se développe horizontalement, de gauche à droite, le pied de page est affiché à droite de la liste.

Les propriétés Header et Footer peuvent être définies sur des valeurs string, comme illustré dans l'exemple suivant :

<CollectionView ItemsSource="{Binding Monkeys}"
                Header="Monkeys"
                Footer="2019">
    ...
</CollectionView>

Le code C# équivalent est :

CollectionView collectionView = new CollectionView
{
    Header = "Monkeys",
    Footer = "2019"
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Ce code génère les captures d’écran suivantes, avec l’en-tête affiché dans la capture d’écran iOS et le pied de page affiché dans la capture d’écran Android :

Capture d'écran d'un CollectionView avec une chaîne en en-tête et en 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 StackLayout qui contient un objet Label :

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.Header>
        <StackLayout BackgroundColor="LightGray">
            <Label Margin="10,0,0,0"
                   Text="Monkeys"
                   FontSize="12"
                   FontAttributes="Bold" />
        </StackLayout>
    </CollectionView.Header>
    <CollectionView.Footer>
        <StackLayout BackgroundColor="LightGray">
            <Label Margin="10,0,0,0"
                   Text="Friends of Xamarin Monkey"
                   FontSize="12"
                   FontAttributes="Bold" />
        </StackLayout>
    </CollectionView.Footer>
    ...
</CollectionView>

Le code C# équivalent est :

StackLayout headerStackLayout = new StackLayout();
header.StackLayout.Add(new Label { Text = "Monkeys", ... } );
StackLayout footerStackLayout = new StackLayout();
footerStackLayout.Add(new Label { Text = "Friends of Xamarin Monkey", ... } );

CollectionView collectionView = new CollectionView
{  
    Header = headerStackLayout,
    Footer = footerStackLayout            
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Ce code génère les captures d’écran suivantes, avec l’en-tête affiché dans la capture d’écran iOS et le pied de page affiché dans la capture d’écran Android :

Capture d'écran de l'en-tête et du pied de page de CollectionView utilisant des vues.

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 :

<CollectionView ItemsSource="{Binding Monkeys}"
                Header="{Binding .}"
                Footer="{Binding .}">
    <CollectionView.HeaderTemplate>
        <DataTemplate>
            <StackLayout BackgroundColor="LightGray">
                <Label Margin="10,0,0,0"
                       Text="Monkeys"
                       FontSize="12"
                       FontAttributes="Bold" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.HeaderTemplate>
    <CollectionView.FooterTemplate>
        <DataTemplate>
            <StackLayout BackgroundColor="LightGray">
                <Label Margin="10,0,0,0"
                       Text="Friends of Xamarin Monkey"
                       FontSize="12"
                       FontAttributes="Bold" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.FooterTemplate>
    ...
</CollectionView>

Le code C# équivalent est :

CollectionView collectionView = new CollectionView
{
    HeaderTemplate = new DataTemplate(() =>
    {
        return new StackLayout { };
    }),
    FooterTemplate = new DataTemplate(() =>
    {
        return new StackLayout { };
    })
};
collectionView.SetBinding(ItemsView.HeaderProperty, ".");
collectionView.SetBinding(ItemsView.FooterProperty, ".");
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Ce code génère les captures d’écran suivantes, avec l’en-tête affiché dans la capture d’écran iOS et le pied de page affiché dans la capture d’écran Android :

Capture d'écran de l'en-tête et du pied de page de CollectionView utilisant des modèles.

Espacement des éléments

Par défaut, il n’y a pas d’espace entre chaque élément dans un CollectionView. Ce comportement peut être modifié en définissant des propriétés sur la disposition des éléments utilisés par le CollectionView.

Lorsqu’un CollectionView définit sa propriété ItemsLayout sur un objet LinearItemsLayout, la propriété LinearItemsLayout.ItemSpacing peut être définie sur une valeur double qui représente l’espace entre les éléments :

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical"
                           ItemSpacing="20" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Remarque

La propriété LinearItemsLayout.ItemSpacing a un rappel de validation défini, qui garantit que la valeur de la propriété est toujours supérieure ou égale à 0.

Le code C# équivalent est :

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
    {
        ItemSpacing = 20
    }
};

Ce code donne une liste verticale à une seule colonne avec un espacement de 20 entre les éléments :

Capture d'écran de CollectionView avec espacement des éléments.

Lorsqu’une propriété CollectionView définit sa propriété ItemsLayout sur un objet GridItemsLayout, les propriétés GridItemsLayout.VerticalItemSpacing et GridItemsLayout.HorizontalItemSpacing peuvent être définies sur des valeurs double qui représentent l’espace vide verticalement et horizontalement entre les éléments :

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
       <GridItemsLayout Orientation="Vertical"
                        Span="2"
                        VerticalItemSpacing="20"
                        HorizontalItemSpacing="30" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Remarque

Les propriétés GridItemsLayout.VerticalItemSpacing et GridItemsLayout.HorizontalItemSpacing ont des rappels de validation définis, ce qui garantit que les valeurs des propriétés sont toujours supérieures ou égales à 0.

Le code C# équivalent est :

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
    {
        VerticalItemSpacing = 20,
        HorizontalItemSpacing = 30
    }
};

Ce code donne une grille verticale à deux colonnes avec un espacement vertical de 20 entre les éléments et un espacement horizontal de 30 entre les éléments :

Capture d'écran d’un CollectionView avec espacement des éléments dans une grille.

Dimensionnement des éléments

Par défaut, chaque élément dans un CollectionView est mesuré et dimensionné individuellement, à condition que les éléments de l’interface utilisateur dans le DataTemplate ne spécifient pas de tailles fixes. Ce comportement, qui peut être modifié, est spécifié par la valeur de la propriété CollectionView.ItemSizingStrategy. Cette valeur de propriété peut être définie sur l'un des membres de l'énumération ItemSizingStrategy :

  • MeasureAllItems : chaque élément est mesuré individuellement. Il s’agit de la valeur par défaut.
  • MeasureFirstItem : seul le premier élément est mesuré, avec tous les éléments suivants ayant la même taille que le premier élément.

Important

La stratégie de dimensionnement MeasureFirstItem entraîne une augmentation des performances lorsqu’elle est utilisée dans les situations où la taille de l’élément est destinée à être uniforme sur tous les éléments.

L’exemple de code suivant montre comment définir la propriété ItemSizingStrategy :

<CollectionView ...
                ItemSizingStrategy="MeasureFirstItem">
    ...
</CollectionView>

Le code C# équivalent est :

CollectionView collectionView = new CollectionView
{
    ...
    ItemSizingStrategy = ItemSizingStrategy.MeasureFirstItem
};

Redimensionnement dynamique des éléments

Les éléments d’un CollectionView peuvent être redimensionnés dynamiquement au moment de l’exécution en modifiant les propriétés associées à la disposition des éléments dans le DataTemplate. Par exemple, l’exemple de code suivant modifie les propriétés HeightRequest et WidthRequest d’un objet Image :

void OnImageTapped(object sender, EventArgs e)
{
    Image image = sender as Image;
    image.HeightRequest = image.WidthRequest = image.HeightRequest.Equals(60) ? 100 : 60;
}

Le gestionnaire d’événements OnImageTapped est exécuté en réponse à un objet Image en cours d’accès et modifie les dimensions de l’image, afin qu’il soit plus facilement consulté :

Capture d’écran d’un CollectionView avec dimensionnement d’élément dynamique.

Disposition de droite à gauche

Pour que CollectionView 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="CollectionViewDemos.Views.VerticalListFlowDirectionPage"
             Title="Vertical list (RTL FlowDirection)"
             FlowDirection="RightToLeft">
    <Grid Margin="20">
        <CollectionView ItemsSource="{Binding Monkeys}">
            ...
        </CollectionView>
    </Grid>
</ContentPage>

La valeur par défaut de FlowDirection pour un élément avec un parent est MatchParent. Par conséquent, le CollectionView hérite de la valeur de la propriété FlowDirection à partir du Grid, qui hérite à son tour de la valeur de la propriété FlowDirection de ContentPage. Cela donne la disposition de droite à gauche montrée dans la capture d'écran suivante :

Capture d'écran d'une disposition de liste verticale de CollectionView de droite à gauche.

Pour plus d’informations sur le sens du flux, consultez Localisation de droite à gauche.