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