Lier à soi-même / ‘this’ dans XAML

Question WPF / XAML simple. Dans XAML, comment faire référence à l’object Self / this dans un contexte donné? Dans une application très basique avec une fenêtre principale, un contrôle et une propriété C # codée de la fenêtre, je souhaite associer une propriété du contrôle à la propriété codée manuellement de la fenêtre.

Dans le code, c’est très facile – dans le constructeur de Windows, j’ai ajouté ceci:

Binding bind = new Binding(); bind.Source = this; bind.Path = new PropertyPath("ButtonWidth"); button1.SetBinding(WidthProperty, bind); 

De toute évidence, j’ai une propriété appelée ButtonWidth, et un contrôle appelé button1. Je ne peux pas comprendre comment faire cela dans XAML. Diverses tentatives comme l’exemple suivant n’ont pas fonctionné:

 

etc

Merci

Commencez par utiliser une virgule entre le RelativeSource et le Path dans votre liaison:

  

Deuxièmement, le RelativeSource se lie au bouton. Le bouton n’a pas de propriété appelée ButtonWidth. Je suppose que vous devez vous lier au contrôle de votre parent.

Essayez donc cette liaison RelativeSource:

  

Une des façons de gérer RelativeSource et autres consiste à nommer l’élément XAML racine:

      

Si vous souhaitez définir le DataContext, vous pouvez également le faire:

      

Je trouve que ceci est un bon truc pour ne pas avoir à se rappeler toutes les complexités de la liaison RelativeSource.

Je pense que ce que vous cherchez est le suivant:

  

Le problème de nommer l’élément racine XAML est que, si vous prenez l’habitude d’utiliser le même nom (par exemple, “_this”, “Root”, etc.) pour toutes les racines de votre projet, la liaison tardive dans les modèles peuvent accéder au mauvais élément. En effet, lorsque {Binding} ElementName=... est utilisé dans un Template , les noms sont résolus à l’exécution en remontant l’arborescence NameScope jusqu’à ce que la première correspondance soit trouvée.

La solution de Clint évite de nommer l’élément racine, mais définit l’élément racine dans son propre DataContext , qui peut ne pas être une option si le DataContext est nécessaire, par exemple, pour des données. Il semble également un peu lourd d’introduire une autre liaison sur un élément dans le seul but d’y donner access. Plus tard, si l’access n’est plus nécessaire, cette {Binding} deviendra encombrée: la responsabilité de l’access appartient à la cible et à la liaison.

En conséquence, voici une simple extension de balisage pour accéder à l’élément racine XAML sans le nommer:

 using System.Xaml; using System.Windows.Markup; public sealed class XamlRootExtension : MarkupExtension { public override Object ProvideValue(IServiceProvider sp) { var rop = sp.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider; return rop == null ? null : rop.RootObject; } }; 

XAML:

    

Résultat:

entrer la description de l'image ici


nb

pour plus de clarté, aucun clr-namespace n’est utilisé, mais notez que le XAML montré ici fonctionne réellement pour accéder à l’espace de noms global (bien que le concepteur VS2013 se plaint)

Malheureusement, nommer l’élément racine avec “ElementName = ..” semble être le seul moyen avec UWP car {RelativeSource Self} n’y est pas supporté.

Curieusement, cela fonctionne toujours lorsque le nom est remplacé dans la mise en page, par exemple

   

puis

    

BTW, Windows 10 a corrigé une erreur (présente dans Windows 8.1), lorsque le même nom interne est utilisé pour différents éléments dans la même disposition.

Cependant, je préférerais utiliser {RelativeSource Self}, car cela me semble plus logique et plus sûr.