See Sharp
Is it really just a matter of point of view ?

it's PART_Ytime, baby !

August 29, 2008 12:23 by salfab

Introduction 

Aujourd'hui, jettons un oeil à ces étranges Named Template Parts que l'on peut parfois voir dans les Templates de certains contrôles, et qui sont facilement reconnaissable au préfixe PART_

Qu'est-ce que ce PART_ ?

De façon à pouvoir rendre un CustomControl hautement Templateable (Anglicisme fait maison qui signifie "un truc qu'on peut lui appliquer un template dessus"), il va nous falloir poser quelques contraintes. En effet : Si l'utilisateur de notre contrôle peut entièrement le re-templater, qui nous assure qu'un certain élément sur lequel nous nous reposons est toujours existant ?

Exemple : SalFab crée une TextBox en 3D. Ce contrôle s'appelle évidemment SalFab3DTextBox, et contient dans son template par défaut, en plus de tout l'attirail nécessaire à la gestion de la 3D, un élément TextBox qui contiendra le texte à entrer - Le nerf de la guerre. Comme SalFab désire ardemment que tout le monde utilise son contrôle, il décide de permettre au monde entier de changer le template de son contrôle. Comment être sûr que l'utilisateur utilise bel et bien un élément TextBox dans son template ? Rappellons que toute la logique du contrôle se repose sur le postulat qu'il existe un tel élément dans son template !

L'idée est de donner un nom prédéfini à cet élément ( grâce à la propriété x:Name du TextBox ), par exemple, "PART_UnderLyingTextBox". Afin de pouvoir travailler avec dans le codebehind, nous aimerions en récupérer une référence. Ceci peut se faire dans la méthode OnApplyTemplate de notre contrôle, grâce à un appel de la méthode GetTemplateChild("PART_UnderLyingTextBox"). Le paramètre de la méthode est bien entendu le nom, arbitraire, de notre élément. Il nous sera alors possible de lui appliquer la logique applicative désirée. Par exemple, enregistrer son évènement TextChanged. On pourra également tester si le retour de GetTemplateChild est null, et adapter le comportement du contrôle en conséquence.

Si le nom à donner à x:Name est bien arbitraire, l'usage veut que pour ce genre d'utilisation, l'on utilise le préfixe PART_.

Notons qu'il ne s'agit pas là d'un nom réservé, mais d'une convention de codage. Par conséquent, il sera judicieux de documenter explicitement les Parts utilisées par notre contrôle, chose qui peut être faite à l'aide de l'attribut TemplatePartAttribute

Par exemple, dans notre cas :

[TemplatePart(Name = "PART_UnderLyingTextBox", Type = typeof(TextBox))]

Notons finalement que l'attribut TemplatePartAttribute n'applique aucun comportement, mais est uniquement présent pour décrire les parts utilisées. Cet attribut ser utilisé par des outils de design pour mettre en évidence leur existence.

 Happy Templating !