Dispositions pouvant être liées dans Xamarin.Forms

Télécharger l’exemple Télécharger l’exemple

Les dispositions pouvant être liées permettent à n’importe quelle 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 de définir l’apparence de chaque élément avec un DataTemplate. Les dispositions pouvant être liées sont fournies par la BindableLayout classe, qui expose les propriétés jointes 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 qui sera utilisé pour choisir un DataTemplate pour un élément au moment de l’exécution.

Notes

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

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

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

Notes

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

Toutes ces propriétés peuvent être attachées aux AbsoluteLayoutclasses , FlexLayout, Grid, RelativeLayoutet StackLayout 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, chaque élément de la collection est ajouté à la collection pour être Layout<T>.Children affiché par la disposition. La Layout<T>classe dérivée 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.

Les dispositions pouvant être liées ne doivent être utilisées que lorsque la collection d’éléments à afficher est petite et que le défilement et la sélection ne sont pas nécessaires. Bien que le défilement puisse être fourni en encapsulant une disposition pouvant être liée dans un ScrollView, cela n’est pas recommandé, car les dispositions pouvant être liées ne sont pas virtualisés par l’interface utilisateur. Lorsque le défilement est requis, une vue défilement qui inclut la virtualisation de l’interface utilisateur, telle que ListView ou CollectionView, doit être utilisée. 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 à n’importe quelle classe de disposition qui dérive de la Layout<T> classe, il n’est pas toujours pratique de le faire, en particulier pour les AbsoluteLayoutclasses , Gridet RelativeLayout . Par exemple, envisagez le scénario de vouloir afficher une collection de données dans un à l’aide d’une Grid disposition pouvant être liée, où chaque élément de la collection est un objet contenant plusieurs propriétés. Chaque ligne du Grid doit afficher un objet de la collection, chaque colonne de l’objet Grid affichant l’une des propriétés de l’objet. Étant donné que le DataTemplate pour la disposition pouvant être liée ne peut contenir qu’un seul objet, il est nécessaire que cet objet soit une classe de disposition contenant plusieurs vues qui affichent chacune l’une des propriétés de l’objet dans une colonne spécifique Grid . Bien que ce scénario puisse être réalisé avec des dispositions pouvant être liées, il en résulte un parent Grid contenant un enfant Grid pour chaque élément de la collection liée, ce qui est une utilisation très inefficace et problématique de la Grid disposition.

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

Une disposition pouvant être liée est remplie avec des données en définissant sa ItemsSource propriété sur n’importe quelle collection qui implémente IEnumerable, et en l’attachant à une Layout<T>classe dérivée :

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

Le code C# équivalent est :

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

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

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

L’apparence de chaque élément dans la disposition pouvant être liée peut être définie en définissant la BindableLayout.ItemTemplate propriété jointe 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 est affiché par une CircleImage vue définie dans :DataTemplate

Disposition pouvant être liée avec une disposition 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

L’apparence de chaque élément dans la disposition pouvant être liée peut être choisie au moment de l’exécution, en fonction de la valeur de l’élément, en définissant la BindableLayout.ItemTemplateSelector propriété jointe sur :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);

Le DataTemplateSelector utilisé dans l’exemple d’application 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 TechItemTemplateSelector classe définit DefaultTemplate et XamarinFormsTemplateDataTemplate les propriétés qui sont définies 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 à côté, 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 une disposition 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

La EmptyView propriété peut être définie sur une chaîne, qui sera affichée par un Label lorsque la ItemsSource propriété est null, ou lorsque la collection spécifiée par la ItemsSource propriété est null ou vide. Le code XAML suivant montre un exemple de ce scénario :

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

Le résultat est que lorsque la collection liée aux données est null, la chaîne définie comme valeur de propriété EmptyView s’affiche :

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

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

La EmptyView propriété peut être définie sur une vue, qui s’affiche lorsque la ItemsSource propriété est null, ou lorsque la collection spécifiée par la ItemsSource propriété est null ou vide. Il peut s’agir d’une vue unique ou d’une vue qui contient plusieurs vues enfants. L’exemple XAML suivant montre la EmptyView propriété définie sur une vue qui contient 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>

Le résultat est que lorsque la collection liée aux données est null, les StackLayout vues enfants et sont affichées.

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

De même, le EmptyViewTemplate peut être défini sur , DataTemplatequi s’affiche lorsque la ItemsSource propriété est null, ou lorsque la collection spécifiée par la ItemsSource propriété est null ou vide. peut DataTemplate contenir une seule vue ou une vue qui contient plusieurs vues enfants. En outre, le BindingContext de EmptyViewTemplate sera hérité du BindingContext du de .BindableLayout L’exemple XAML suivant montre la EmptyViewTemplate propriété 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>

Le résultat est que lorsque la collection liée aux données est null, le Label dans est DataTemplate affiché :

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

Notes

La EmptyViewTemplate propriété ne peut pas être définie via un DataTemplateSelector.

Choisir un EmptyView au moment de l’exécution

Les vues qui seront affichées en tant que EmptyView lorsque les données ne sont pas disponibles peuvent être définies en tant qu’objets ContentView dans un ResourceDictionary. La EmptyView propriété peut ensuite être définie sur un , en fonction d’une logique métier spécifique ContentView, au moment de l’exécution. Le code 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 CODE XAML définit deux ContentView objets au niveau ResourceDictionaryde la page , l’objet Switch contrôlant l’objet qui ContentView sera défini comme valeur de propriété EmptyView . Lorsque le Switch est basculé, le OnEmptyViewSwitchToggled gestionnaire d’événements exécute la ToggleEmptyView méthode :

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

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

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