Astuces DotNet (Sébastien Courtois)

04/03/2009

[Silverlight 2] Insertion d’un Tooltip dans l’en-tête du Datagrid

Filed under: Intermediaire, Silverlight, XAML — Étiquettes : , , , , — sebastiencourtois @ 15:26

Arrivé avec la RTW de Silverlight 2, le contrôle Datagrid permet d’afficher des données de façon structurées sous la forme d’une grille. Sa simplicité d’utilisation et sa personnalisation assez complète en XAML en font un objet indispensable pour toutes les interfaces Silverlight métiers (i.e autres que du jeu ou de la vidéo :)). Toutefois, cette personnalisation peut s’avérer complexe lorsqu’on souhaite modifier certaines parties qui n’ont pas été conçu pour être modifié … facilement.

J’ai une grille de données avec des en-têtes de colonnes se nommant “Header 1”,”Header 2” …. Pour chaque en-tête, je souhaite avoir un message lorsque je passe ma souris dessus.

Blog1

(Si vous êtes pressé, la solution se trouve à la fin du post)

Processus de recherche / Explications :

Je décide de rajouter ToolTipService.Tooltip=”test”  dans la balise d’un des DataGridTextColumn car cette propriété m’est proposée par l’IntelliSense.

Blog3-2J’obtiens une exception à l’exécution m’indiquant que le ToolTipService.Tooltip est un attribut inconnu pour l’élément DataGridTextColumn. (Texte exact : "XAML Parse Exception : Unknown attribute ToolTipService.ToolTip on element DataGridTextColumn.“)

ToolTipService est une propriété statique dans la classe FrameworkElement.

Blog3-5 Blog3-4

En analysant les hiérarchies ci dessus, on s’aperçoit que DataGridTextColumn ne dépend pas de FrameworkElement. Il faut donc utiliser une classe dérivant de FrameworkElement afin d’avoir accès à cette propriété. L’idée est donc de remplacer le texte de l’en-tête par un FrameworkElement de son choix (dans notre cas, un TextBlock) et de renseigner sa propriété ToolTipService.Tooltip.

Lorsqu’on regarde les propriétés disponibles pour les en-têtes pour le DataGridTextColumn, on s’aperçoit que les choix sont limités

Blog3-3La propriété Header ne prend que des chaines de caractères permettant de changer le titre. La propriété HeaderStyle permet de définir un Style pour l’en-tête. Pas de HeaderTemplate ou de propriétés de Template pour l’en-tête de colonne directement accessible par DataGridTextColumn.

L’astuce suivante a été trouvé par une collègue de travail: Simon Ferquel (MVP Silverlight).

En analysant la classe DataGridColumn dans Reflector, on peut voir que une propriété HeaderCell de visibilité internal. Cette propriété est de type DataGridColumnHeader dans le namespace System.Windows.Controls.Primitives. DataGridColumnHeader étant un ContentControl, on peut utiliser son ContentTemplate pour mettre tous les FrameworkElement que l’on souhaite :). Ne pouvant pas passer directement par la propriété HeaderCell à cause de sa visibilité, on utilise la propriété HeaderStyle pour faire la modification de l’en-tête.

Solution :

On utilise la propriété HeaderStyle de DataGridTextColumn pour redéfinir son HeaderCell. En XAML, cela donne :

Blog3-8Attention à ne pas oublier la ligne d’ajout du namespace au début du fichier XAML :

Blog3-9

Il est noté que cette exemple fonctionne avec toutes les classes héritant de DataGridColumn et pas uniquement pour DataGridTextColumn. 

Résultat final (le curseur de la souris a disparu lors de la capture) : Blog3-10

Propulsé par WordPress.com.