Partager via


Dispositions pouvant être liées dans Xamarin.Forms

Les dispositions pouvant être liées permettent à toute classe de disposition qui dérive de la Layout<T> classe de générer son contenu en liant à une collection d’éléments, avec l’option permettant 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.

Toutes ces propriétés peuvent être attachées aux AbsoluteLayoutclasses , , FlexLayoutStackLayout GridRelativeLayoutet les classes qui dérivent toutes de la Layout<T> classe.

La Layout<T> classe expose une Children collection à laquelle les éléments enfants d’une disposition sont ajoutés. Lorsque la BindableLayout.ItemsSource propriété est définie sur une collection d’éléments et attachée à une Layout<T>classe dérivée de -, chaque élément de la collection est ajouté à la Layout<T>.Children collection pour l’affichage par la disposition. La classe dérivée de Layout<T> met ensuite à jour ses vues enfants lorsque la collection sous-jacente change. Pour plus d’informations sur le cycle de Xamarin.Forms disposition, consultez Création d’une disposition personnalisée.

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 Layout<T> classe, il n’est pas toujours pratique de le faire, en particulier pour les classesGrid, et RelativeLayout les AbsoluteLayoutclasses. 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<T> :

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

Le code C# équivalent est :

IEnumerable<string> items = ...;
var 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>
            <controls:CircleImage Source="{Binding}"
                                  Aspect="AspectFill"
                                  WidthRequest="44"
                                  HeightRequest="44"
                                  ... />
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</StackLayout>

Le code C# équivalent est :

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

Dans cet exemple, chaque élément de la TopFollowers collection s’affiche par une CircleImage vue définie dans les DataTemplateéléments suivants :

Disposition pouvant être liée avec un DataTemplate

Pour plus d’informations sur les modèles de données, consultez Xamarin.Forms Modèles de données.

Choisir l’apparence de l’élément au moment de l’exécution

Vous pouvez choisir l’apparence de chaque élément dans 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 { ... };
var flexLayout = new FlexLayout();
BindableLayout.SetItemsSource(flexLayout, viewModel.User.FavoriteTech);
BindableLayout.SetItemTemplateSelector(flexLayout, dataTemplateSelector);

L’exemple DataTemplateSelector d’application utilisé est illustré dans l’exemple suivant :

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

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        return (string)item == "Xamarin.Forms" ? XamarinFormsTemplate : DefaultTemplate;
    }
}

La classe TechItemTemplateSelector définit les propriétés DefaultTemplate et XamarinFormsTemplate DataTemplate, qui sont configurées sur différents modèles de données. La OnSelectTemplate méthode retourne le XamarinFormsTemplate, qui affiche un élément en rouge foncé avec un cœur en regard de celui-ci, lorsque l’élément est égal à «Xamarin.Forms ». Lorsque l’élément n’est pas égal à «Xamarin.Forms », la OnSelectTemplate méthode retourne le DefaultTemplate, qui affiche un élément à l’aide de la couleur par défaut d’un Label:

Disposition pouvant être liée avec un DataTemplateSelector

Pour plus d’informations sur les sélecteurs de modèles de données, consultez Création d’un Xamarin.Forms 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 :

Capture d’écran d’une vue vide de chaîne de disposition pouvant être liée, sur iOS et Android

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.

Capture d’écran d’une vue vide de disposition pouvant être liée avec plusieurs vues, sur iOS et Android

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

Capture d’écran d’un modèle d’affichage vide de disposition pouvant être lié, sur iOS et Android

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ée :

Capture d’écran du choix d’affichage vide lors de l’exécution, sur iOS et Android