Partager via


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 :

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

  1. Activez la compilation XAML. Pour plus d’informations sur la compilation XAML, consultez Compilation XAML.
  2. Définissez un attribut x:DataType sur un objet VisualElement correspondant au type de l’objet auquel VisualElement 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 BoxViewLabel é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 :

Sélecteur de couleurs compilé

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 :

Liste de couleurs compilée

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 ou TwoWay) 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 liaison OneWay, OneWayToSource ou TwoWay) est environ 5 fois plus rapide que la définition du BindingContext 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 liaison OneTime) est environ 7 fois plus rapide que la définition du BindingContext 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.