Organiser les vues avec Grid

Effectué

Supposons que vous créez une page qui affiche des images dans une grille de 7 x 5. Vous pouvez créer cette page avec plusieurs conteneurs StackLayout horizontaux et verticaux. Toutefois, ce serait fastidieux à coder et pourrait entraîner des problèmes de performances en raison des exigences de mémoire et de traitement nécessaires pour gérer plusieurs panneaux de disposition. Pour les interfaces utilisateur qui nécessitent à la fois des lignes et des colonnes, il vaut mieux choisir le panneau de disposition Grid. Dans cette unité, vous apprenez à définir une Grid et à placer des vues à l’intérieur de ses cellules.

Qu’est-ce qu’un Grid ?

Une Grid est un panneau de disposition constitué de lignes et de colonnes. L’illustration suivante montre la vue conceptuelle d’une grille.

Illustration showing an example grid with rows and columns of boxes, with one box spanning multiple rows and columns.

Vous placez des vues dans les cellules qui sont créées à l’intersection des lignes et des colonnes. Par exemple, si vous créez une Grid avec trois colonnes et deux lignes, six cellules sont disponibles pour les vues. Les lignes et les colonnes peuvent avoir des tailles différentes ou s’adapter automatiquement à la taille des enfants qu’elles contiennent. Les vues enfants peuvent occuper une seule cellule ou s’étendre sur plusieurs cellules. Cette flexibilité fait de Grid un bon choix de panneau de disposition racine pour de nombreuses applications.

Comment spécifier les lignes et les colonnes d’une grille

Lorsque vous créez un Grid, vous pouvez définir chaque ligne et colonne individuellement. Ce système vous donne un contrôle total sur la hauteur de chaque ligne et la largeur de chaque colonne. Chaque Grid a une collection d’objets RowDefinition et ColumnDefinition qui définissent la forme de la grille. Vous remplissez ces collections avec des instances de RowDefinition et ColumnDefinition, chacune représentant une ligne ou une colonne dans votre interface utilisateur.

Voici deux extraits de code qui montrent les définitions de classe pour RowDefinition et ColumnDefinition :

public sealed class RowDefinition : ...
{
    ...
    public GridLength Height { get; set; }
}
public sealed class ColumnDefinition : ...
{
    ...
    public GridLength Width { get; set; }
}

Notez que RowDefinition a une propriété appelée Height et ColumnDefinition une propriété appelée Width. Vous utilisez ces propriétés pour définir la hauteur d’une ligne et la largeur d’une colonne, comme décrit dans les sections suivantes.

Qu’est-ce que GridLength ?

Le type de données pour les propriétés Width et Height est GridLength. Ce type contient deux propriétés : GridUnitType et Value. Voici un extrait de code qui montre une partie de la définition de type.

public struct GridLength
{
    ...
    public GridUnitType GridUnitType { get; }
    public double Value { get; }
}

Vous pouvez définir la propriété GridUnitType sur l’une des valeurs suivantes :

  • Absolute
  • Auto
  • Star

Examinons de plus près chacune de ces valeurs.

Absolute GridUnitType

Absolute spécifie que la ligne ou la colonne doit avoir une taille fixe. Vous utilisez la propriété Value pour indiquer la taille. Voici un exemple qui montre comment définir la hauteur d’une ligne sur une taille fixe de 100 unités d’appareil en C#. Notez comment vous utilisez le constructeur GridLength, qui prend une valeur numérique. Ce constructeur définit automatiquement GridUnitType sur Absolute pour vous.

var row = new RowDefinition() { Height = new GridLength(100) };

En XAML, vous fournissez simplement une valeur numérique. L’analyseur XAML appelle un convertisseur de type pour créer l’instance GridLength. Voici un exemple qui montre la même chose en XAML :

<RowDefinition Height="100" />

Auto GridUnitType

Auto adapte automatiquement la taille de la ligne ou de la colonne à vos vues enfants. La Grid analyse toutes les vues enfants dans cette ligne ou colonne, sélectionne la plus grande et définit une taille de ligne ou de colonne suffisamment grande pour contenir cet enfant. Quand vous créez une définition de ligne dans le code, la valeur numérique est ignorée. Vous pouvez utiliser n’importe quelle valeur. Voici un exemple qui montre comment définir la hauteur d’une ligne sur une taille automatique en C#. Notez que nous avons choisi arbitrairement la valeur 1.

var row = new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) };

En XAML, vous utilisez la valeur Auto. Voici un exemple qui montre la même chose en XAML.

<RowDefinition Height="Auto" />

Star GridUnitType

Star applique des dimensions proportionnelles. Avec des dimensions proportionnelles, l’espace total disponible et le rapport demandé par chaque ligne ou colonne déterminent la taille. Dans le langage courant, on parle souvent de redimensionnement proportionnel (star sizing en anglais).

Examinons en détail le processus de redimensionnement proportionnel pour les lignes d’une grille.

  1. Déterminer l’espace disponible : Le Grid analyse toutes les lignes qui n’utilisent Grid le redimensionnement proportionnel. Il additionne la hauteur de toutes les lignes et soustrait ce nombre total de sa propre hauteur (hauteur du Grid). Ce calcul nous donne la quantité d’espace disponible pour toutes les lignes redimensionnées de manière proportionnelle.

  2. Répartir l’espace disponible : Le Grid répartit ensuite l’espace disponible entre toutes les lignes redimensionnées de manière proportionnelle selon le paramètre Value de chaque ligne. La propriété Value sert de multiplicateur pour déterminer le ratio de toutes les lignes redimensionnées de manière proportionnelle. Par exemple, si nous avons deux lignes redimensionnées de manière proportionnelle, toutes deux avec un multiplicateur 1, l’espace disponible est réparti entre les deux. Toutefois, si l’une d’elles a un paramètre 2 égal à la valeur, elle obtient deux fois plus d’espace que l’autre.

Voici un exemple montrant comment définir la hauteur d’une ligne avec 2 Star en C# :

var row = new RowDefinition() { Height = new GridLength(2, GridUnitType.Star) };

En XAML, vous utilisez le symbole * pour représenter le redimensionnement proportionnel. Vous associez la valeur et le caractère * dans une seule chaîne, et un convertisseur de type crée pour vous le GridLength. Voici le même exemple en XAML.

<RowDefinition Height="2*" />

Collections de grilles

Une fois que vous avez défini des lignes et des colonnes à l’aide de RowDefinition et de ColumnDefinition, vous pouvez les ajouter à une Grid. Vous utilisez les propriétés de collection RowDefinitions et ColumnDefinitions de Grid. Le remplissage de ces collections est le plus souvent effectué en XAML.

Cet exemple montre comment définir quatre lignes et les ajouter à un Grid à l’aide de la propriété RowDefinitions :

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="100" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="1*" />
        <RowDefinition Height="2*" />
    </Grid.RowDefinitions>
    ...
</Grid>

Cette définition peut être raccourcie comme suit :

<Grid RowDefinitions="100, Auto, 1*, 2*">
    ...
</Grid>

Le code XAML qui définit des colonnes est le même que celui-ci, sauf que vous utilisez ColumnDefinitions et que vous définissez la largeur.

Au moment de l’exécution, ce code XAML produit une Grid de quatre lignes. La première ligne a une hauteur fixe de 100 unités d’appareil. La deuxième ligne a la hauteur de la vue la plus grande dans la ligne. Les troisième et quatrième lignes utilisent le redimensionnement proportionnel, ce qui signifie qu’elles prennent l’espace restant et le répartissent proportionnellement en fonction de leur multiplicateur Value. Comme la troisième ligne est 1* et que la quatrième est 2*, la quatrième ligne a deux fois la hauteur de la troisième ligne.

Taille de ligne et colonne par défaut

La taille par défaut des lignes et des colonnes est 1*. Par exemple, regardez le XAML suivant.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    ...
</Grid>

Cette définition peut être raccourcie comme suit :

<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">
    ...
</Grid>

Comme aucune des lignes ou des colonnes n’a de taille spécifiée, 1* est appliqué à chacune d’entre elles. Au moment de l’exécution, cette configuration crée une Grid uniforme, c’est-à-dire que toutes les lignes ont la même hauteur et toutes les colonnes ont la même largeur.

Comment ajouter des vues à une grille

Quand vous ajoutez une vue à un Grid, vous l’ajoutez à une cellule spécifique. Les cellules sont créées au croisement des lignes et des colonnes. Pour positionner une vue dans une cellule, vous devez connaître l’emplacement de la cellule. Vous utilisez une combinaison de numéros de ligne et de colonne pour identifier une cellule.

Numérotation des lignes et des colonnes

La numérotation des lignes et des colonnes commence à zéro. L’origine se trouve en haut à gauche. Voici l’illustration de la numérotation d’un Grid de quatre lignes et deux colonnes.

Illustration showing a grid with four rows and two columns. The numbering is shown for each row and column. Starting from the top-left box at column zero and row zero, to the bottom-right box at column 1 and row 3.

Par exemple, pour ajouter une vue à la cellule en bas à droite, la position de la vue est row 3 column 1

Ajouter une vue à une grille à l’aide des propriétés jointes

Vous avez besoin d’une méthode pour spécifier le numéro de ligne et de colonne d’une vue quand vous l’ajoutez à une grille. L’une des options est de définir les propriétés Row et Column sur la classe de base View pour pouvoir spécifier la position sur la vue directement. Cette technique fonctionne, mais n’est pas la plus efficace. Les vues ne sont pas toujours dans un Grid et ces propriétés ne sont donc pas toujours nécessaires. Une meilleure approche consiste à utiliser les propriétés jointes.

Une propriété jointe est une propriété définie dans une classe, mais sur des objets d’autres types.

Les propriétés jointes sont comme une collection de paires clé-valeur faisant partie d’une vue. Lorsque vous ajoutez une vue à un Grid, vous spécifiez la ligne et la colonne. Les propriétés jointes vous permettent d’ajouter une paire clé-valeur avec la clé Grid.Row et une valeur qui spécifie le numéro de ligne. Quand la Grid est prête à positionner la vue, elle cherche dans la collection une clé appelée Grid.Row. Si elle existe, la Grid utilise la valeur pour positionner la vue.

Cet exemple montre comment créer un Grid et ajouter une vue à l’aide des propriétés jointes :

<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">

    <BoxView Grid.Row="1" Grid.Column="0" Color="Navy" />
    
</Grid>

Dans cet exemple, Grid.Row=1 et Grid.Column=0 sont des paires clé-valeur ajoutées à une collection interne de BoxView. La Grid utilise ces valeurs pour déterminer l’emplacement de la vue. Voici à quoi ressemble le Grid si vous exécutez l’application sur un appareil.

Illustration showing a Grid with three rows and two columns. A BoxView is displayed in the second row of the first column.

Comment étendre une vue sur plusieurs lignes ou colonnes

Il existe deux autres propriétés jointes : Grid.RowSpan et Grid.ColumnSpan. Ces propriétés spécifient le nombre de lignes ou de colonnes que la vue doit occuper. Par exemple, regardez le XAML suivant.

<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">

    <BoxView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Color="Navy" />
    
</Grid>

Notez que cet exemple définit la valeur ColumnSpan sur 2. Cette vue occupe deux colonnes à partir de Column 0. Voici à quoi ressemble le Grid si vous exécutez l’application sur un appareil.

Illustration showing a Grid with three rows and two columns. A BoxView is positioned in the second row of the first column and spans both columns.

Contrôle des connaissances

1.

Quelle est l’utilité de Star GridUnitType ?