Extension de balisage {x:Bind}

Remarque Pour plus d’informations sur l’utilisation de la liaison de données dans votre application avec {x:Bind} (et pour une comparaison entre {x:Bind} et {Binding}), voir Présentation détaillée de la liaison de données.

L’extension de balisage {x:Bind}, nouveauté de Windows 10, peut être utilisée en remplacement de la méthode {Binding}. {x:Bind} s’exécute en moins de temps et moins de mémoire que {Binding} et prend en charge un meilleur débogage.

Lors de la compilation du XAML, l’extension de balisage {x : Bind} est convertie en code qui récupère une valeur à partir d’une propriété sur une source de données et la définit sur la propriété spécifiée dans le balisage. L’objet de liaison peut éventuellement être configuré pour observer les modifications apportées à la valeur de la propriété de source de données et s’actualiser en fonction de ces modifications (Mode="OneWay"). Elle peut également être configurée éventuellement pour renvoyer les modifications apportées à sa propre valeur à la propriété source (Mode="TwoWay").

Les objets de liaison créés par {x:Bind} et {Binding} sont en grande partie équivalents du point de vue fonctionnel. Toutefois, {x:Bind} exécute un code spécial qu’il génère au moment de la compilation, et {Binding} utilise une inspection d’objet runtime à usage général. Par conséquent, les liaisons {x:Bind} (souvent appelées des liaisons compilées) offrent des performances remarquables, valident vos expressions de liaison lors de la compilation, et prennent en charge le débogage en vous permettant de définir des points d’arrêt dans les fichiers de code générés en tant que la classe partielle pour votre page. Ces fichiers se trouvent dans votre dossier obj, et portent des noms tels que <view name>.g.cs (pour C#).

Conseil

{x:Bind} a un mode par défaut de OneTime, contrairement à {Binding}, qui a un mode par défaut de OneWay. Cette option a été choisie pour des raisons de performances, car l’utilisation de OneWay entraîne la génération d’un plus grand nombre de code pour le raccordement et la gestion de la détection des modifications. Vous pouvez spécifier explicitement un mode pour utiliser la liaison OneWay ou TwoWay. Vous pouvez également utiliser x:DefaultBindMode pour modifier le mode par défaut de {x:Bind} pour un segment spécifique de l’arborescence de balisage. Le mode spécifié s’applique à toutes les expressions {x:Bind} sur cet élément et ses enfants, qui ne spécifient pas explicitement un mode dans le cadre de la liaison.

Exemples d’applications illustrant {x:Bind}

Utilisation des attributs XAML

<object property="{x:Bind}" .../>
-or-
<object property="{x:Bind propertyPath}" .../>
-or-
<object property="{x:Bind bindingProperties}" .../>
-or-
<object property="{x:Bind propertyPath, bindingProperties}" .../>
-or-
<object property="{x:Bind pathToFunction.functionName(functionParameter1, functionParameter2, ...), bindingProperties}" .../>
Terme Description
Propertypath Chaîne qui spécifie le chemin de propriété pour la liaison. Pour plus d’informations, voir la section Chemin de propriété ci-dessous.
bindingProperties
Propname=value[, propName=value]* Une ou plusieurs propriétés de liaison spécifiées à l’aide d’une syntaxe constituée d’une ou plusieurs paires nom/valeur.
propName Nom de chaîne de la propriété à définir sur l’objet de liaison. Par exemple, « Convertisseur ».
value Valeur à attribuer à la propriété. La syntaxe de l’argument dépend de la propriété définie. Voici un exemple d’utilisation de lavaleurpropName= où la valeur est elle-même une extension de balisage : Converter={StaticResource myConverterClass}. Pour plus d’informations, voir la section Propriétés que vous pouvez définir avec {x:Bind} ci-dessous.

Exemples

<Page x:Class="QuizGame.View.HostView" ... >
    <Button Content="{x:Bind Path=ViewModel.NextButtonText, Mode=OneWay}" ... />
</Page>

Cet exemple de XAML utilise {x:Bind} avec une propriété ListView.ItemTemplate. Notez la déclaration d’une valeur x:DataType.

  <DataTemplate x:Key="SimpleItemTemplate" x:DataType="data:SampleDataGroup">
    <StackPanel Orientation="Vertical" Height="50">
      <TextBlock Text="{x:Bind Title}"/>
      <TextBlock Text="{x:Bind Description}"/>
    </StackPanel>
  </DataTemplate>

Chemin de la propriété

PropertyPath définit Path pour une expression {x:Bind}. Path est un chemin de propriété spécifiant la valeur de la propriété, de la sous-propriété, du champ ou de la méthode avec lesquels vous établissez la liaison (la source). Vous pouvez mentionner explicitement le nom de propriété Path : {x:Bind Path=...}. Ou vous pouvez l’omettre : {x:Bind ...}.

Résolution de chemin de propriété

{x:Bind} n’utilise pas le DataContext comme source par défaut. Au lieu de cela, elle utilise le contrôle de page ou d’utilisateur proprement dit. Par conséquent, elle apparaît dans le code-behind de votre contrôle de page ou d’utilisateur pour les propriétés, champs et méthodes. Pour exposer votre modèle d’affichage à {x:Bind}, vous devez généralement ajouter des champs ou propriétés au code-behind de votre contrôle de page ou d’utilisateur. Les étapes dans un chemin de propriété sont délimitées par des points (.), et vous pouvez inclure plusieurs délimiteurs pour parcourir des sous-propriétés successives. Utilisez le point délimiteur quel que soit le langage de programmation utilisé pour implémenter l’objet cible de la liaison.

Par exemple : dans une page, Text="{x:Bind Employee.FirstName}" recherche un membre Employee sur la page, puis un membre FirstName sur l’objet renvoyé par Employee. Si vous liez un contrôle d’éléments à une propriété contenant des dépendances d’un employé, votre chemin de propriété pourrait être « Employee.Dependents », et le modèle d’élément du contrôle d’éléments se chargerait de l’affichage des éléments dans « Dependents ».

Pour C++ / CX, {x:Bind} ne peut pas effectuer de liaison à des champs et propriétés privés dans la page ou le modèle de données. Vous devez avoir une propriété publique pour que la liaison soit possible. La surface d’exposition pour la liaison doit être exposée en tant que classes/interfaces CX pour que nous puissions obtenir les métadonnées pertinentes. L’attribut [Bindable] ne doit pas être nécessaire.

Avec x:Bind, vous n’avez pas besoin d’utiliser ElementName=xxx dans l’expression de liaison. Au lieu de cela, vous pouvez utiliser le nom de l’élément comme première partie du chemin d’accès de la liaison, car les éléments nommés deviennent des champs dans la page ou le contrôle utilisateur qui représente la source de liaison racine.

Collections

Si la source de données est une collection, un chemin de propriété peut spécifier les éléments de la collection selon leur position ou index. Par exemple, « Teams[0]. Players », où le littéral « [] » entoure le « 0 » qui demande le premier élément dans une collection à index zéro.

Pour utiliser un indexeur, le modèle doit implémenter IList<T> or IVector<T> sur le type de la propriété à indexer. (Notez que IReadOnlyList<T> et IVectorView<T> ne prennent pas en charge la syntaxe de l’indexeur.) Si le type de la propriété indexée prend en charge INotifyCollectionChanged ou IObservableVector et que la liaison est OneWay ou TwoWay, elle inscrit et écoute les notifications de modification sur ces interfaces. La logique de détection des modifications met à jour en fonction de tous les changements de collection, même si cela n’affecte pas la valeur indexée spécifique. En effet, la logique d’écoute est commune dans toutes les instances de la collection.

Si la source de données est un dictionnaire ou une carte, un chemin de propriété peut spécifier les éléments de la collection par leur nom de chaîne. Par exemple <TextBlock Text="{x:Bind Players['John Smith']} » /> recherche un élément dans le dictionnaire nommé « John Smith ». Le nom doit être entouré de guillemets simples ou doubles. Utilisez l’accent circonflexe (^) comme caractère d’échappement des guillemets dans les chaînes. Il est généralement plus facile d’utiliser d’autres guillemets de ceux utilisés pour l’attribut XAML. (Notez que IReadOnlyDictionary<T> et IMapView<T> ne prennent pas en charge la syntaxe de l’indexeur.)

Pour utiliser un indexeur de chaîne, le modèle doit implémenter IDictionary<string, T> ou IMap<string, T> sur le type de la propriété à indexer. Si le type de la propriété indexée prend en charge IObservableMap et que la liaison est OneWay ou TwoWay, il s’inscrit pour écouter les notifications de modification sur ces interfaces. La logique de détection des modifications met à jour en fonction de tous les changements de collection, même si cela n’affecte pas la valeur indexée spécifique. En effet, la logique d’écoute est commune dans toutes les instances de la collection.

Propriétés attachées

Pour lier des propriétés attachées, vous devez placer la classe et le nom de la propriété entre parenthèses après le point. Par exemple, Text="{x:Bind Button22.(Grid.Row)}". Si la propriété n’est pas déclarée dans un espace de noms Xaml, vous devez la faire précéder d’un espace de noms xml que vous devez mapper à un espace de noms de code au début du document.

Transtypage

Les liaisons compilées sont fortement typées et correspondent au type de chaque étape dans un chemin. Si le type retourné ne comprend pas le membre, il échoue lors de la compilation. Vous pouvez spécifier une conversion pour indiquer à la liaison le type réel de l’objet.

Dans le cas suivant, obj est une propriété d’objet type, mais contient une zone de texte, de sorte que nous pouvons utiliser Text="{x:Bind ((TextBox)obj).Text}" ou Text="{x:Bind obj.(TextBox.Text)}".

Champ groups3 dans Text="{x:Bind ((data:SampleDataGroup)groups3[0]). Title} » étant un dictionnaire d’objets, vous devez le convertir en data:SampleDataGroup. Notez l’utilisation du préfixe d’espace de noms xml data: pour mapper l’objet type à un espace de noms du code qui ne fait pas partie de l’espace de noms XAML par défaut.

Remarque : la syntaxe de cast de type C# est plus souple que la syntaxe de propriété jointe. Elle est désormais recommandée.

Casting sans chemin

L’analyseur de liaison natif ne fournit pas de mot clé à représenter this en tant que paramètre de fonction, mais il prend en charge la conversion sans chemin (par exemple, {x:Bind (x:String)}), qui peut être utilisée comme paramètre de fonction. Par conséquent, {x:Bind MethodName((namespace:TypeOfThis))} est un moyen valide d’effectuer ce qui est conceptuellement équivalent à {x:Bind MethodName(this)}.

Exemple :

Text="{x:Bind local:MainPage.GenerateSongTitle((local:SongItem))}"

<Page
    x:Class="AppSample.MainPage"
    ...
    xmlns:local="using:AppSample">

    <Grid>
        <ListView ItemsSource="{x:Bind Songs}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:SongItem">
                    <TextBlock
                        Margin="12"
                        FontSize="40"
                        Text="{x:Bind local:MainPage.GenerateSongTitle((local:SongItem))}" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>
namespace AppSample
{
    public class SongItem
    {
        public string TrackName { get; private set; }
        public string ArtistName { get; private set; }

        public SongItem(string trackName, string artistName)
        {
            ArtistName = artistName;
            TrackName = trackName;
        }
    }

    public sealed partial class MainPage : Page
    {
        public List<SongItem> Songs { get; }
        public MainPage()
        {
            Songs = new List<SongItem>()
            {
                new SongItem("Track 1", "Artist 1"),
                new SongItem("Track 2", "Artist 2"),
                new SongItem("Track 3", "Artist 3")
            };

            this.InitializeComponent();
        }

        public static string GenerateSongTitle(SongItem song)
        {
            return $"{song.TrackName} - {song.ArtistName}";
        }
    }
}

Fonctions dans les chemins de liaison

À compter de Windows 10, version 1607, {x : Bind} prend en charge l’utilisation d’une fonction comme niveau feuille du chemin de liaison. Il s’agit d’une fonctionnalité puissante pour la liaison de données qui permet plusieurs scénarios de balisage. Pour plus d’informations, consultez liaisons de fonction.

Liaison d’événement

La liaison d’événement est une fonctionnalité unique pour une liaison compilée. Elle vous permet de spécifier le gestionnaire pour un événement à l’aide d’une liaison, au lieu d’une méthode dans le code-behind. Par exemple :Click="{x:Bind rootFrame.GoForward}".

Pour des événements, la méthode cible ne doit pas être surchargée et doit :

  • correspondre à la signature de l’événement ;
  • OU ne pas avoir de paramètres ;
  • OU avoir le même nombre de paramètres des types qui peuvent être assignés à partir des types des paramètres d’événement.

Dans le code-behind généré, la liaison compilés gère l’événement et le route vers la méthode sur le modèle, en évaluant le chemin de l’expression de liaison quand l’événement se produit. Cela signifie que, contrairement aux liaisons de propriété, elle ne suit pas les modifications du modèle.

Pour plus d’informations sur la syntaxe de chaîne pour un chemin de propriété, consultez la Syntaxe de PropertyPath, en gardant à l’esprit les différences décrites ici pour {x:Bind}.

Propriétés que vous pouvez définir avec {x:Bind}

{x:Bind} est illustrée avec la syntaxe de l’espace réservé bindingProperties, car plusieurs propriétés en lecture/écriture peuvent être définies dans l’extension de balisage. Les propriétés peuvent être définies dans n’importe quel ordre avec des paires devaleurspropName= séparées par des virgules. Notez que vous ne pouvez pas inclure de saut de ligne dans l’expression de liaison. Certaines propriétés requièrent des types sans conversion de type. Elles nécessitent donc leurs propres extensions de balisage imbriquées dans l’extension de balisage {x:Bind}.

Ces propriétés fonctionnent de la même façon que les propriétés de la classe Binding .

Propriété Description
Chemin d’accès Voir la section Chemin de propriété ci-dessus.
Converter Spécifie l’objet convertisseur appelé par le moteur de liaison. Le convertisseur peut être défini en XAML, mais uniquement si vous faites référence à une instance d’objet que vous avez assignée dans une référence d’extension de balisage {StaticResource} à cet objet dans le dictionnaire de ressources.
ConverterLanguage Spécifie la culture que doit utiliser le convertisseur. (Si vous définissez ConverterLanguage, vous devez également définir Converter.) La culture est définie comme un identificateur basé sur des normes. Pour plus d’informations, consultez ConverterLanguage.
ConverterParameter Spécifie le paramètre de convertisseur qui peut être utilisé dans la logique du convertisseur. (Si vous définissez ConverterParameter, vous devez également définir Converter.) La plupart des convertisseurs utilisent une logique simple qui obtient toutes les informations de la valeur transmise à convertir et ne nécessitent pas de valeur ConverterParameter. Le paramètre ConverterParameter est destiné aux implémentations de convertisseur moyennement avancées qui comprennent plusieurs logiques basées sur ce qui est transmis dans ConverterParameter. Vous pouvez écrire un convertisseur qui utilise des valeurs autres que des chaînes, mais c’est rare. Pour plus d’informations, voir Remarques dans ConverterParameter .
FallbackValue Spécifie une valeur à afficher quand la source ou le chemin ne peuvent pas être résolus.
Mode Spécifie le mode de liaison, sous la forme de l’une des chaînes suivantes : « OneTime », « OneWay » ou « TwoWay ». La valeur par défaut est « OneTime ». Notez qu’elle diffère de la valeur par défaut {Binding}, qui est « OneWay » dans la plupart des cas.
TargetNullValue Spécifie une valeur à afficher quand la valeur de la source est résolue, mais est explicitement null.
BindBack Spécifie une fonction à utiliser pour le sens inverse d’une liaison bidirectionnelle.
UpdateSourceTrigger Spécifie quand envoyer (push) les modifications du contrôle vers le modèle dans les liaisons TwoWay. La valeur par défaut pour toutes les propriétés à l’exception de TextBox.Text est PropertyChanged ; TextBox.Text est LostFocus.

Notes

Si vous convertissez le balisage de {Binding} en {x:Bind}, tenez compte des différences de valeurs par défaut pour la propriété Mode . x:DefaultBindMode peut être utilisé pour modifier le mode par défaut pour x : Bind pour un segment spécifique de l’arborescence de balisage. Le mode sélectionné applique toutes les expressions x:Bind sur cet élément et ses enfants, qui ne spécifient pas explicitement de mode dans le cadre de la liaison. OneTime est plus performant que OneWay, car l’utilisation de OneWay entraîne la génération d’un plus grand nombre de code pour le raccordement et la gestion de la détection des modifications.

Remarques

Dans la mesure où l’extension de balisage {x:Bind} utilise un code généré pour obtenir ses avantages, elle nécessite des informations de type au moment de la compilation. Cela signifie que vous ne pouvez pas effectuer de liaison à des propriétés quand vous ne connaissez pas le type à l’avance. Pour cette raison, vous ne pouvez pas utiliser {x:Bind} avec la propriété DataContext, qui est du type Object, et est également sujette à modification au moment de l’exécution.

Lorsque vous utilisez {x:Bind} avec des modèles de données, vous devez indiquer le type lié à en définissant une valeur x:DataType , comme indiqué dans la section Exemples . Vous pouvez également définir le type sur une interface ou un type de classe de base, puis utiliser des conversions si nécessaire pour formuler une expression complète.

Les liaisons compilées dépendent de la génération du code. Par conséquent, si vous utilisez {x:Bind} dans un dictionnaire de ressources, ce dernier doit comporter une classe code-behind. Pour un exemple de code, voir Dictionnaires de ressources avec {x:Bind}.

Le code généré des pages et des contrôles utilisateur incluant des liaisons compilées contiendra une propriété « Bindings ». Celle-ci comprend les méthodes suivantes :

  • Update() - Met à jour les valeurs de toutes les liaisons compilées. Toutes les liaisons unidirectionnelles/bidirectionnelles contiennent des écouteurs afin de détecter les modifications.
  • Initialize() - Si les liaisons n’ont pas encore été initialisées, appelle Update() pour initialiser les liaisons.
  • StopTracking() - Déconnecte tous les écouteurs créés pour les liaisons uni- et bidirectionnelles. Elles peuvent être réinitialisées à l’aide de la méthode Update().

Notes

Depuis Windows 10, version 1607, l’infrastructure XAML fournit un convertisseur intégré permettant de convertir un booléen en Visibility. Le convertisseur mappe true à la valeur d’énumération Visible et false à Collapsed afin que vous puissiez lier une propriété Visibility à un booléen sans créer de convertisseur. Notez qu’il ne s’agit pas d’une fonctionnalité de liaison de fonction, mais uniquement d’une liaison de propriété. Pour utiliser le convertisseur intégré, la version du SDK cible de votre application doit être 14393 ou une version ultérieure. Vous ne pouvez pas l’utiliser si votre application cible des versions antérieures de Windows 10. Pour plus d’informations sur les versions cibles, voir Code adaptatif de version.

Conseil Si vous avez besoin de spécifier une accolade simple pour une valeur, comme dans Path ou ConverterParameter, faites-la précéder d’une barre oblique inverse : \{. Vous pouvez également placer l’ensemble de la chaîne qui contient les accolades à échapper dans une paire de guillemets secondaire. Par exemple : ConverterParameter='{Mix}'.

Converter, ConverterLanguage et ConverterLanguage sont tous liés au scénario de conversion d’une valeur ou d’un type de la source de liaison en type ou valeur compatible avec la propriété cible de liaison. Pour obtenir plus d’informations et des exemples, voir la section « Conversions de données » de Présentation détaillée de la liaison de données.

{x:Bind} est uniquement une extension de balisage. Il n’existe aucun moyen de créer ou manipuler de telles liaisons par programmation. Pour plus d’informations sur les extensions de balisage, voir Vue d’ensemble du langage XAML.