Xamarin.Forms Liaisons compilées
Les liaisons compilées sont résolues plus rapidement que les liaisons classiques, ce qui améliore les performances de liaison de données dans les Xamarin.Forms applications.
Les liaisons de données présentent deux problèmes principaux :
- Aucune validation des expressions de liaison n’a lieu au moment de la compilation. À la place, les liaisons sont résolues au moment de l’exécution. Par conséquent, les liaisons non valides ne sont pas détectées avant l’exécution, lorsque l’application ne se comporte pas comme prévu ou que des messages d’erreur apparaissent.
- Elles ne sont pas rentables. Les liaisons sont résolues au moment de l’exécution via l’inspection (réflexion) des objets à usage général et la surcharge de cette opération varie d’une plateforme à l’autre.
Les liaisons compilées améliorent les performances de liaison de données dans les applications en Xamarin.Forms résolvant les expressions de liaison au moment de la compilation plutôt que dans le runtime. En outre, cette validation des expressions de liaison au moment de la compilation favorise une meilleure expérience de dépannage pour les développeurs, car les liaisons non valides sont signalées comme erreurs de build.
Le processus permettant d’utiliser des liaisons compilées est le suivant :
- Activez la compilation XAML. Pour plus d’informations sur la compilation XAML, consultez Compilation XAML.
- Définissez un attribut
x:DataType
sur un objetVisualElement
correspondant au type de l’objet auquelVisualElement
et ses enfants seront liés.
Remarque
Il est recommandé de définir l’attribut x:DataType
dans la hiérarchie d’affichage au niveau où BindingContext
est défini. Cependant, cet attribut peut être redéfini à tout emplacement dans une hiérarchie d’affichage.
Pour utiliser des liaisons compilées, l’attribut x:DataType
doit être défini sur un littéral de chaîne ou un type à l’aide de l’extension de balisage x:Type
. Au moment de la compilation XAML, toutes les expressions de liaison non valides seront signalées comme erreurs de build. Toutefois, le compilateur XAML signalera uniquement une erreur de build pour la première expression de liaison non valide qu’il rencontrera. Toutes les expressions de liaison valides qui sont définies sur l’objet VisualElement
ou ses enfants seront compilées, que BindingContext
soit défini en XAML ou dans le code. La compilation d’une expression de liaison génère du code compilé qui obtiendra une valeur d’une propriété de la source et la définira sur la propriété de la cible spécifiée dans le balisage. En outre, en fonction de l’expression de liaison, le code généré peut observer des modifications dans la valeur de la propriété source et actualiser la propriété cible, et il peut renvoyer (push) des modifications à partir de la cible vers la source.
Important
Les liaisons compilées sont actuellement désactivées pour toutes les expressions de liaison qui définissent la propriété Source
. Cela tient au fait que la propriété Source
est toujours définie à l’aide de l’extension de balisage x:Reference
, qui ne peut pas être résolue au moment de la compilation.
Utiliser des liaisons compilées
La page Sélecteur de couleurs compilée illustre l’utilisation de liaisons compilées entre Xamarin.Forms les vues et les propriétés viewmodel :
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataBindingDemos"
x:Class="DataBindingDemos.CompiledColorSelectorPage"
Title="Compiled Color Selector">
...
<StackLayout x:DataType="local:HslColorViewModel">
<StackLayout.BindingContext>
<local:HslColorViewModel Color="Sienna" />
</StackLayout.BindingContext>
<BoxView Color="{Binding Color}"
... />
<StackLayout Margin="10, 0">
<Label Text="{Binding Name}" />
<Slider Value="{Binding Hue}" />
<Label Text="{Binding Hue, StringFormat='Hue = {0:F2}'}" />
<Slider Value="{Binding Saturation}" />
<Label Text="{Binding Saturation, StringFormat='Saturation = {0:F2}'}" />
<Slider Value="{Binding Luminosity}" />
<Label Text="{Binding Luminosity, StringFormat='Luminosity = {0:F2}'}" />
</StackLayout>
</StackLayout>
</ContentPage>
La racine StackLayout
instancie HslColorViewModel
et initialise la propriété Color
dans les balises d’élément de propriété pour la propriété BindingContext
. Cette racine StackLayout
définit également l’attribut x:DataType
comme type viewmodel, indiquant que toutes les expressions de liaison dans la hiérarchie d’affichage racine StackLayout
seront compilées. Cela peut être vérifié en modifiant l’une des expressions de liaison pour la lier à une propriété de viewmodel inexistante, ce qui entraînera une erreur de build. Bien que cet exemple définisse l’attribut x:DataType
comme un littéral de chaîne, il peut également être défini comme un type à l’aide de l’extension de balisage x:Type
. Pour plus d’informations sur l’extension de balisage x:Type
, consultez la section x:Type Markup Extension.
Important
L’attribut x:DataType
peut être redéfini à tout emplacement dans une hiérarchie d’affichage.
Les éléments BoxView
, Label
et les vues Slider
héritent du contexte de liaison de StackLayout
. Ces vues sont toutes des cibles de liaison qui référencent les propriétés sources dans le viewmodel. Pour la propriété BoxView.Color
et la propriété Label.Text
, les liaisons de données sont OneWay
- les propriétés dans la vue sont définies à partir des propriétés dans le viewmodel. Toutefois, la propriété Slider.Value
utilise une liaison TwoWay
. Cela permet à chaque Slider
d’être défini à partir du viewmodel, et également au viewmodel d’être défini à partir de chaque Slider
.
Lorsque l’application est exécutée pour la première fois, les BoxView
Label
éléments et Slider
les éléments sont tous définis à partir du viewmodel en fonction de la propriété initiale Color
définie lorsque le viewmodel a été instancié. Ceci est illustré dans les captures d’écran suivantes :
Lorsque les curseurs sont manipulés, les éléments BoxView
et Label
sont mis à jour en conséquence.
Pour plus d’informations sur ce sélecteur de couleur, consultez ViewModels et notifications de modification de propriété.
Utilisation des liaisons compilées dans un DataTemplate
Les liaisons figurant dans un DataTemplate
sont interprétées dans le contexte de l’objet basé sur le modèle. Par conséquent, lorsque vous utilisez des liaisons compilées dans un DataTemplate
, le DataTemplate
doit déclarer le type de son objet de données à l’aide de l’attribut x:DataType
.
La page Compiled Color List (Liste de couleurs compilée) illustre l’utilisation des liaisons compilées dans un DataTemplate
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataBindingDemos"
x:Class="DataBindingDemos.CompiledColorListPage"
Title="Compiled Color List">
<Grid>
...
<ListView x:Name="colorListView"
ItemsSource="{x:Static local:NamedColor.All}"
... >
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:NamedColor">
<ViewCell>
<StackLayout Orientation="Horizontal">
<BoxView Color="{Binding Color}"
... />
<Label Text="{Binding FriendlyName}"
... />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!-- The BoxView doesn't use compiled bindings -->
<BoxView Color="{Binding Source={x:Reference colorListView}, Path=SelectedItem.Color}"
... />
</Grid>
</ContentPage>
La propriété ListView.ItemsSource
est définie sur la propriété NamedColor.All
statique. La classe NamedColor
utilise la réflexion .NET pour énumérer tous les champs publics statiques dans la structure Color
et pour les stocker avec leurs noms dans une collection accessible à partir de la propriété All
statique. Par conséquent, l’objet ListView
est rempli avec toutes les instances de NamedColor
. Pour chaque élément figurant dans ListView
, le contexte de liaison de l’élément est défini sur un objet NamedColor
. Les éléments BoxView
et Label
dans l’objet ViewCell
sont liés aux propriétés de NamedColor
.
Notez que le DataTemplate
définit l’attribut x:DataType
en tant que type de NamedColor
, ce qui indique que toutes les expressions de liaison figurant dans la hiérarchie d’affichage DataTemplate
seront compilées. Cela peut être vérifié en modifiant les expressions de liaison à lier à une propriété de NamedColor
inexistante, ce qui entraînera une erreur de build. Bien que cet exemple définisse l’attribut x:DataType
comme un littéral de chaîne, il peut également être défini comme un type à l’aide de l’extension de balisage x:Type
. Pour plus d’informations sur l’extension de balisage x:Type
, consultez la section x:Type Markup Extension.
À la première exécution de l’application, ListView
est rempli avec les instances de NamedColor
. Lorsqu’un élément dans ListView
est sélectionné, la propriété BoxView.Color
est définie sur la couleur de l’élément sélectionné dans ListView
:
La sélection d’autres éléments dans l’objet ListView
met à jour la couleur de l’objet BoxView
.
Combiner des liaisons compilées avec des liaisons classiques
Les expressions de liaison sont compilées uniquement pour la hiérarchie d’affichage sur laquelle l’attribut x:DataType
est défini. À l’inverse, toutes les vues dans une hiérarchie sur laquelle l’attribut x:DataType
n’est pas défini utiliseront des liaisons classiques. Par conséquent, il est possible de combiner des liaisons compilées et classiques sur une page. Par exemple, dans la section précédente, les vues figurant dans le DataTemplate
utilisent des liaisons compilées, alors que ce n’est pas le cas du BoxView
qui est défini sur la couleur sélectionnée dans l’objet ListView
.
La structuration prudente des attributs x:DataType
permet ainsi d’obtenir une page utilisant des liaisons compilées et classiques. Vous pouvez également redéfinir l’attribut x:DataType
à tout moment dans une hiérarchie d’affichage sur null
à l’aide de l’extension de balisage x:Null
. Cela indique que toutes les expressions de liaison figurant dans la hiérarchie d’affichage utiliseront des liaisons classiques. La page Mixed Bindings (Liaisons mixtes) illustre cette approche :
<StackLayout x:DataType="local:HslColorViewModel">
<StackLayout.BindingContext>
<local:HslColorViewModel Color="Sienna" />
</StackLayout.BindingContext>
<BoxView Color="{Binding Color}"
VerticalOptions="FillAndExpand" />
<StackLayout x:DataType="{x:Null}"
Margin="10, 0">
<Label Text="{Binding Name}" />
<Slider Value="{Binding Hue}" />
<Label Text="{Binding Hue, StringFormat='Hue = {0:F2}'}" />
<Slider Value="{Binding Saturation}" />
<Label Text="{Binding Saturation, StringFormat='Saturation = {0:F2}'}" />
<Slider Value="{Binding Luminosity}" />
<Label Text="{Binding Luminosity, StringFormat='Luminosity = {0:F2}'}" />
</StackLayout>
</StackLayout>
Le StackLayout
racine définit l’attribut x:DataType
en tant que type HslColorViewModel
, ce qui indique que toutes les expressions de liaison figurant dans la hiérarchie d’affichage StackLayout
racine seront compilées. Toutefois, le StackLayout
interne redéfinit l’attribut x:DataType
sur null
avec l’expression de balisage x:Null
. Par conséquent, les expressions de liaison figurant dans le StackLayout
interne utilisent des liaisons classiques. Seul l’objet BoxView
, au sein de la hiérarchie d’affichage StackLayout
racine, utilise des liaisons compilées.
Pour plus d'informations sur l’expression de balisage x:Null
, consultez Extension de balisage x:Null.
Performances
Les liaisons compilées améliorent de façon variable les performances de liaison de données. Les tests unitaires révèlent que :
- Une liaison compilée qui utilise la notification de modification de propriété (c'est-à-dire une liaison
OneWay
,OneWayToSource
ouTwoWay
) est résolue environ 8 fois plus vite qu’une liaison classique. - Une liaison compilée qui n’utilise pas la notification de modification de propriété (c'est-à-dire une liaison
OneTime
) est résolue environ 20 fois plus vite qu’une liaison classique. - La définition du
BindingContext
sur une liaison compilée qui utilise la notification de modification de propriété (c'est-à-dire une liaisonOneWay
,OneWayToSource
ouTwoWay
) est environ 5 fois plus rapide que la définition duBindingContext
sur une liaison classique. - La définition du
BindingContext
sur une liaison compilée qui n’utilise pas la notification de modification de propriété (c'est-à-dire une liaisonOneTime
) est environ 7 fois plus rapide que la définition duBindingContext
sur une liaison classique.
Ces différences de performances peuvent être accrues sur les appareils mobiles, selon la plateforme utilisée, la version du système d’exploitation utilisé et l’appareil sur lequel l’application s’exécute.