Share via


BindableLayout

Browse sample. Parcourir l'exemple

Les dispositions pouvant être liées .NET MAUI (.NET Multi-Platform App UI) permettent à toute classe de disposition dérivée de la classe Layout de générer son contenu en se liant à une collection d’éléments, avec l’option de définir l’apparence de chaque élément avec un DataTemplate.

Les dispositions pouvant être liées sont fournies par la classe BindableLayout, qui expose les propriétés attachées suivantes :

  • ItemsSource : spécifie la collection d’éléments IEnumerable à afficher par la disposition.
  • ItemTemplate : spécifie le DataTemplate à appliquer à chaque élément de la collection d’éléments affichés par la disposition.
  • ItemTemplateSelector : spécifie le DataTemplateSelector utilisé pour choisir un DataTemplate pour un élément au moment de l’exécution.

Remarque

La propriété ItemTemplate est prioritaire lorsque les propriétés ItemTemplate et ItemTemplateSelector sont toutes deux définies.

En outre, la classe BindableLayout expose les propriétés pouvant être liées suivantes :

  • EmptyView : spécifie le string ou la vue qui est affiché lorsque la propriété ItemsSource est null ou lorsque la collection spécifiée par la propriété ItemsSource est null ou vide. La valeur par défaut est null.
  • EmptyViewTemplate : spécifie le DataTemplate qui est affiché lorsque la propriété ItemsSource est null ou lorsque la collection spécifiée par la propriété ItemsSource est null ou vide. La valeur par défaut est null.

Remarque

La propriété EmptyViewTemplate est prioritaire lorsque les propriétés EmptyView et EmptyViewTemplate sont toutes deux définies.

Vous pouvez attacher toutes ces propriétés aux classes AbsoluteLayout, FlexLayout, Grid, HorizontalStackLayout, StackLayout et VerticalStackLayout, qui dérivent toutes de la classe Layout.

Lorsque la propriété BindableLayout.ItemsSource est définie sur une collection d’éléments et attachée à une classe dérivée de Layout, chaque élément de la collection est ajouté à la classe dérivée de Layout pour l’affichage. La classe dérivée de Layout met ensuite à jour ses vues enfants lorsque la collection sous-jacente change.

Utilisez uniquement des dispositions pouvant être liées lorsque la collection d’éléments à afficher est petite et que le défilement et la sélection ne sont pas obligatoires. Bien que vous puissiez encapsuler une disposition pouvant être liée dans ScrollView à des fins de défilement, nous vous déconseillons de le faire dans la mesure où les dispositions pouvant être liées n’incluent pas la virtualisation de l’interface utilisateur. Si un défilement est requis, utilisez une vue avec défilement qui inclut la virtualisation de l’interface utilisateur, comme ListView ou CollectionView. Le non-respect de cette recommandation peut entraîner des problèmes de performances.

Important

Bien qu’il soit techniquement possible d’attacher une disposition pouvant être liée à une classe de disposition qui dérive de la classe Layout, il n’est pas toujours pratique de le faire, en particulier pour les classes AbsoluteLayout et Grid. Par exemple, imaginons que vous souhaitiez afficher une collection de données dans Grid à l’aide d’une disposition pouvant être liée, où chaque élément de la collection est un objet contenant plusieurs propriétés. Chaque ligne dans Grid doit afficher un objet de la collection, et chaque colonne dans Grid doit afficher l’une des propriétés de l’objet. Étant donné que le DataTemplate de la disposition pouvant être liée ne peut contenir qu’un seul objet, cet objet doit être une classe de disposition contenant plusieurs vues, chacune d’entre elles affichant l’une des propriétés de l’objet dans une colonne Grid spécifique. Si vous utilisez des dispositions pour réaliser ce scénario, vous obtenez un parent Grid contenant un enfant Grid pour chaque élément de la collection liée, ce qui constitue une utilisation très inefficace et problématique de la disposition Grid.

Remplir une disposition pouvant être liée avec des données

Pour remplir une disposition pouvant être liée avec des données, définissez sa propriété ItemsSource sur n’importe quelle collection implémentant IEnumerable et attachez-la à une classe dérivée de Layout :

<Grid BindableLayout.ItemsSource="{Binding Items}" />

Le code C# équivalent est :

IEnumerable<string> items = ...;
Grid grid = new Grid();
BindableLayout.SetItemsSource(grid, items);

Lorsque la propriété attachée BindableLayout.ItemsSource est définie sur une disposition, mais que la propriété attachée BindableLayout.ItemTemplate n’est pas définie, chaque élément de la collection IEnumerable est affiché par un Label créé par la classe BindableLayout.

Définir l’apparence de l’élément

Vous pouvez définir l’apparence de chaque élément dans la disposition pouvant être liée en définissant la propriété attachée BindableLayout.ItemTemplate sur un DataTemplate :

<StackLayout BindableLayout.ItemsSource="{Binding User.TopFollowers}"
             Orientation="Horizontal"
             ...>
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding}"
                   Aspect="AspectFill"
                   WidthRequest="44"
                   HeightRequest="44"
                   ... />
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</StackLayout>

Le code C# équivalent est :

DataTemplate imageTemplate = ...;
StackLayout stackLayout = new StackLayout();
BindableLayout.SetItemsSource(stackLayout, viewModel.User.TopFollowers);
BindableLayout.SetItemTemplate(stackLayout, imageTemplate);

Dans cet exemple, chaque élément de la collection TopFollowers est affiché par une vue Image définie dans le DataTemplate :

.NET MAUI bindable layout with a DataTemplate.

Pour plus d’informations sur les modèles de données, consultez 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 la disposition pouvant être liée au moment de l’exécution, en fonction de la valeur de l’élément, en définissant la propriété attachée BindableLayout.ItemTemplateSelector sur un DataTemplateSelector :

<FlexLayout BindableLayout.ItemsSource="{Binding User.FavoriteTech}"
            BindableLayout.ItemTemplateSelector="{StaticResource TechItemTemplateSelector}"
            ... />

Le code C# équivalent est :

DataTemplateSelector dataTemplateSelector = new TechItemTemplateSelector { ... };
FlexLayout flexLayout = new FlexLayout();
BindableLayout.SetItemsSource(flexLayout, viewModel.User.FavoriteTech);
BindableLayout.SetItemTemplateSelector(flexLayout, dataTemplateSelector);

L’exemple suivant présente la classe TechItemTemplateSelector :

public class TechItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate DefaultTemplate { get; set; }
    public DataTemplate MAUITemplate { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        return (string)item == ".NET MAUI" ? MAUITemplate : DefaultTemplate;
    }
}

La classe TechItemTemplateSelector définit les propriétés DataTemplateDefaultTemplate et MAUITemplate définies sur différents modèles de données. La méthode OnSelectTemplate retourne le MAUITemplate, qui affiche un élément en rouge foncé avec un cœur en regard de celui-ci lorsque l’élément est égal à « .NET MAUI ». Si l’élément n’est pas égal à « .NET MAUI », la méthode OnSelectTemplate retourne le DefaultTemplate, qui affiche un élément en utilisant la couleur par défaut d’un Label :

.NET MAUI bindable layout with a DataTemplateSelector.

Pour plus d’informations sur les sélecteurs de modèles de données, consultez Créer un DataTemplateSelector.

Afficher une chaîne lorsque les données ne sont pas disponibles

Vous pouvez définir la propriété EmptyView sur une chaîne, celle-ci étant affichée par un Label lorsque la propriété ItemsSource est null ou lorsque la collection spécifiée par la propriété ItemsSource est null ou vide. Le XAML suivant montre un exemple de ce scénario :

<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}"
             BindableLayout.EmptyView="No achievements">
    ...
</StackLayout>

Ainsi, lorsque la collection liée aux données est null, la chaîne définie comme valeur de propriété EmptyView est affichée :

Screenshot of a bindable layout string empty view.

Afficher des vues lorsque les données ne sont pas disponibles

Vous pouvez définir la propriété EmptyView sur une vue, celle-ci étant affichée lorsque la propriété ItemsSource est null ou lorsque la collection spécifiée par la propriété ItemsSource est null ou vide. Il peut s’agir d’une vue unique ou d’une vue contenant plusieurs vues enfants. L’exemple XAML suivant illustre la propriété EmptyView définie sur une vue contenant plusieurs vues enfants :

<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}">
    <BindableLayout.EmptyView>
        <StackLayout>
            <Label Text="None."
                   FontAttributes="Italic"
                   FontSize="{StaticResource smallTextSize}" />
            <Label Text="Try harder and return later?"
                   FontAttributes="Italic"
                   FontSize="{StaticResource smallTextSize}" />
        </StackLayout>
    </BindableLayout.EmptyView>
    ...
</StackLayout>

Ainsi, lorsque la collection liée aux données est null, StackLayout et ses vues enfants sont affichés.

Screenshot of a bindable layout empty view with multiple views.

De même, vous pouvez définir EmptyViewTemplate sur un DataTemplate, celui-ci étant affiché lorsque la propriété ItemsSource est null ou lorsque la collection spécifiée par la propriété ItemsSource est null ou vide. Le DataTemplate peut contenir une vue unique ou une vue contenant plusieurs vues enfants. En outre, le BindingContext du EmptyViewTemplate est hérité du BindingContext du BindableLayout. L’exemple XAML suivant montre la propriété EmptyViewTemplate définie sur un DataTemplate qui contient une vue unique :

<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}">
    <BindableLayout.EmptyViewTemplate>
        <DataTemplate>
            <Label Text="{Binding Source={x:Reference usernameLabel}, Path=Text, StringFormat='{0} has no achievements.'}" />
        </DataTemplate>
    </BindableLayout.EmptyViewTemplate>
    ...
</StackLayout>

Ainsi, lorsque la collection liée aux données est null, le Label dans le DataTemplate est affiché :

Screenshot of a bindable layout empty view template.

Remarque

Vous ne pouvez pas définir la propriété EmptyViewTemplate via un DataTemplateSelector.

Choisir un EmptyView au moment de l’exécution

Les vues affichées comme EmptyView lorsque les données ne sont pas disponibles peuvent être définies en tant qu’objets ContentView dans un ResourceDictionary. Vous pouvez ensuite définir la propriété EmptyView sur un ContentView spécifique, en fonction d’une logique métier, au moment de l’exécution. Le XAML suivant montre un exemple de ce scénario :

<ContentPage ...>
    <ContentPage.Resources>
        ...    
        <ContentView x:Key="BasicEmptyView">
            <StackLayout>
                <Label Text="No achievements."
                       FontSize="14" />
            </StackLayout>
        </ContentView>
        <ContentView x:Key="AdvancedEmptyView">
            <StackLayout>
                <Label Text="None."
                       FontAttributes="Italic"
                       FontSize="14" />
                <Label Text="Try harder and return later?"
                       FontAttributes="Italic"
                       FontSize="14" />
            </StackLayout>
        </ContentView>
    </ContentPage.Resources>

    <StackLayout>
        ...
        <Switch Toggled="OnEmptyViewSwitchToggled" />

        <StackLayout x:Name="stackLayout"
                     BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}">
            ...
        </StackLayout>
    </StackLayout>
</ContentPage>

Le XAML définit deux objets ContentView au niveau de la page ResourceDictionary, l’objet Switch contrôlant l’objet ContentView qui sera défini comme valeur de propriété EmptyView. Lorsque le Switch est basculé, le gestionnaire d’événements OnEmptyViewSwitchToggled exécute la méthode ToggleEmptyView :

void ToggleEmptyView(bool isToggled)
{
    object view = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
    BindableLayout.SetEmptyView(stackLayout, view);
}

La méthode ToggleEmptyView définit la propriété EmptyView de l’objet StackLayout sur l’un des deux objets ContentView stockés dans le ResourceDictionary, en fonction de la valeur de la propriété Switch.IsToggled. Ensuite, lorsque la collection liée aux données est null, l’objet ContentView défini comme propriété EmptyView est affiché.