Xamarin.Forms Chemin de liaison

Dans tous les exemples précédents de liaison de données, la propriété Path de la classe Binding (ou la propriété Path de l’extension de balisage Binding) a été définie sur une propriété unique. Il est en fait possible de définir Path sur une sous-propriété (une propriété d’une propriété) ou un membre d’une collection.

Par exemple, supposons que votre page contient un TimePicker :

<TimePicker x:Name="timePicker">

La propriété Time de TimePicker est de type TimeSpan, mais vous voulez peut-être créer une liaison de données qui référence la propriété TotalSeconds de cette valeur TimeSpan. Voici la liaison de données :

{Binding Source={x:Reference timePicker},
         Path=Time.TotalSeconds}

La propriété Time est de type TimeSpan, qui a une propriété TotalSeconds. Les propriétés Time et TotalSeconds sont simplement connectées par un point. Les éléments figurant dans la chaîne Path référencent toujours les propriétés et non pas les types de ces propriétés.

Cet exemple et plusieurs autres sont illustrés dans la page Path Variations (Variations de chemin d’accès) :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:globe="clr-namespace:System.Globalization;assembly=netstandard"
             x:Class="DataBindingDemos.PathVariationsPage"
             Title="Path Variations"
             x:Name="page">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Label">
                <Setter Property="FontSize" Value="Large" />
                <Setter Property="HorizontalTextAlignment" Value="Center" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout Margin="10, 0">
        <TimePicker x:Name="timePicker" />

        <Label Text="{Binding Source={x:Reference timePicker},
                              Path=Time.TotalSeconds,
                              StringFormat='{0} total seconds'}" />

        <Label Text="{Binding Source={x:Reference page},
                              Path=Content.Children.Count,
                              StringFormat='There are {0} children in this StackLayout'}" />

        <Label Text="{Binding Source={x:Static globe:CultureInfo.CurrentCulture},
                              Path=DateTimeFormat.DayNames[3],
                              StringFormat='The middle day of the week is {0}'}" />

        <Label>
            <Label.Text>
                <Binding Path="DateTimeFormat.DayNames[3]"
                         StringFormat="The middle day of the week in France is {0}">
                    <Binding.Source>
                        <globe:CultureInfo>
                            <x:Arguments>
                                <x:String>fr-FR</x:String>
                            </x:Arguments>
                        </globe:CultureInfo>
                    </Binding.Source>
                </Binding>
            </Label.Text>
        </Label>

        <Label Text="{Binding Source={x:Reference page},
                              Path=Content.Children[1].Text.Length,
                              StringFormat='The second Label has {0} characters'}" />
    </StackLayout>
</ContentPage>

Dans le deuxième objet Label, la source de la liaison est la page elle-même. La propriété Content est de type StackLayout, qui a une propriété Children de type IList<View>, qui a une propriété Count qui indique le nombre d’enfants.

Chemins d’accès avec indexeurs

La liaison figurant dans le troisième objet Label dans les pages Path Variations référence la classe CultureInfo dans l’espace de noms System.Globalization :

<Label Text="{Binding Source={x:Static globe:CultureInfo.CurrentCulture},
                      Path=DateTimeFormat.DayNames[3],
                      StringFormat='The middle day of the week is {0}'}" />

La source est définie sur la propriété CultureInfo.CurrentCulture statique, qui est un objet de type CultureInfo. Cette classe définit une propriété nommée DateTimeFormat de type DateTimeFormatInfo qui contient une collection DayNames. L’index sélectionne le quatrième élément.

Le quatrième objet Label fait quelque chose de similaire mais pour la culture associée à la France. La propriété Source de la liaison est définie sur l’objet CultureInfo avec un constructeur :

<Label>
    <Label.Text>
        <Binding Path="DateTimeFormat.DayNames[3]"
                 StringFormat="The middle day of the week in France is {0}">
            <Binding.Source>
                <globe:CultureInfo>
                    <x:Arguments>
                        <x:String>fr-FR</x:String>
                    </x:Arguments>
                </globe:CultureInfo>
            </Binding.Source>
        </Binding>
    </Label.Text>
</Label>

Consultez Transmission des arguments de constructeur pour plus d’informations sur la spécification des arguments de constructeur en XAML.

Enfin, le dernier exemple est similaire au second, à ceci près qu’il fait référence à l’un des enfants de StackLayout :

<Label Text="{Binding Source={x:Reference page},
                      Path=Content.Children[1].Text.Length,
                      StringFormat='The first Label has {0} characters'}" />

Cet enfant est un objet Label, qui a une propriété Text de type String, qui a une propriété Length. Le premier objet Label signale le TimeSpan défini dans TimePicker, de sorte que lorsque ce texte est modifié, le dernier objet Label change également.

Voici le programme en cours d’exécution :

Path Variations (Variations de chemin)

Débogage de chemins complexes

Les définitions de chemins complexes peuvent être difficiles à construire : vous devez connaître le type de chaque sous-propriété ou le type des éléments dans la collection pour ajouter correctement la sous-propriété suivante, mais les types eux-mêmes n’apparaissent pas dans le chemin. Une bonne technique consiste à générer le chemin de façon incrémentielle et d’examiner les résultats intermédiaires. Pour ce dernier exemple, vous pouvez commencer sans aucune définition Path :

<Label Text="{Binding Source={x:Reference page},
                      StringFormat='{0}'}" />

Ceci affiche le type de la source de la liaison, ou DataBindingDemos.PathVariationsPage. Vous savez que PathVariationsPage dérive de ContentPage et possède donc une propriété Content :

<Label Text="{Binding Source={x:Reference page},
                      Path=Content,
                      StringFormat='{0}'}" />

Le type de la propriété Content est désormais révélé comme Xamarin.Forms.StackLayout. Ajoutez la Children propriété au Path type et le type est Xamarin.Forms.ElementCollection'1[Xamarin.Forms.View], qui est une classe interne à Xamarin.Forms, mais évidemment un type de collection. Ajoutez un index à ceci et le type est Xamarin.Forms.Label. Continuez de cette façon.

Comme Xamarin.Forms traite le chemin de liaison, il installe un PropertyChanged gestionnaire sur n’importe quel objet du chemin d’accès qui implémente l’interface INotifyPropertyChanged . Par exemple, la liaison finale réagit à une modification dans le premier objet Label, car la propriété Text change.

Si une propriété dans le chemin de liaison n’implémente pas INotifyPropertyChanged, toutes les modifications apportées à cette propriété sont ignorées. Certaines modifications pourraient invalider entièrement le chemin de liaison et vous devriez utiliser cette technique uniquement lorsque la chaîne des propriétés et les sous-propriétés ne deviennent jamais non valides.