Blog de Julien Corioland (MSP)

Quand les technologies .NET deviennent passion...

[WPF] Créer un gestionnaire de thèmes

Windows Presentation Foundation offre d’énormes possibilités en matière de design d’interface. Dans ce post, je vous propose une implémentation possible d’un gestionnaire de thèmes.

Nous allons voir comment faire en sorte de pouvoir changer facilement le thème d’une application, mais aussi faire en sorte de pouvoir rajouter des fichiers de thème à celle-ci, sans avoir à la recompiler.

Comment organiser son application pour utiliser des thèmes ?

Ce qu’il faut savoir avant tout, c’est que tous les contrôles que vous utilisez en WPF sont, par défaut, dépourvu de rendu graphique. Ils utilisent cependant un thème par défaut, défini dans les binaires de WPF.

Ce que l’on appel communément “thème” ou “skin” en WPF n’est rien d’autre qu’un dictionaire de ressources (Resource Dictionary), c’est à dire un fichier écrit en XAML dans lequel nous allons pouvoir définir des styles, des templates (contrôle et données) ou encore des brush etc…

Toutes ces entités seront identifiées soit par une clé (x:Key) soit directement par un type (TargetType). Elles seront ensuite référencée par les contrôles de votre application.

Lors du développement d’un application WPF qui utilise des thèmes, une bonne pratique consiste, comme on le fait dans tous développement web depuis des années, à isoler toutes informations concernant l’affichage dans ces fameux dictionaires de ressources.

Commencez par créer un nouveau projet WPF dans lequel vous créez un dossier “Themes”. Ajoutez un premier dictionaire de ressources à ce dossier :

WpfThemes01

Dans ce fichier nous allons tout simplement définir deux SolidBrush, l’un pour la couleur de fond de notre application, l’autre pour la couleur du texte (je reste simple au niveau du thème pour me concentrer sur la mise en place du gestionnaire) :

WpfThemes02

Remarquez que ces deux ressources sont identifiées par une clé unique dans tous le dictionaire.

Faites en sorte que votre fichier de thème soit compilé comme du contenu et copié en sortie lors de la compilation (ce qui permettra d’ajouter des dictionaires de ressources sans recompiler) :

WpfThemes03

Définissons à présent ce fichier comme dictionaire de ressources pour notre application. Pour cela, deux solutions sont possibles :

En XAML, dans App.xaml :

WpfThemes04

Par le code, dans App.xaml.cs :

WpfThemes05

Il ne vous reste plus qu’à référencer les ressources dans votre interface graphique, à l’aide du mot clé “DynamicResource”, ce qui permettra de les changer dynamiquement :

WpfThemes06

Création du gestionnaire de thème

Maintenant que nous avons vu comment mettre en place un thème pour notre application, je vous propose de voir une implémentation possible de gestionnaire de thème. Pour faire bien les choses, je vais utiliser le pattern MV/VM combiné au pattern Attached Behaviors. Je vous conseil de passer par le blog de Thomas Lebrun pour comprendre ces deux patterns.

Commençons par la classe ThemesManager qui permettra de charger et changer le thème de l’application au runtime.

Celle-ci ne définit qu’une seule propriété, ThemesCollection, de type NameValueCollection :

WpfThemes07

Une méthode privée LoadThemes permet, lors de l’instanciation de la classe, d’aller explorer le dossier “Themes” en sortie de notre application, d’y récupérer tous les fichiers “.xaml” et de les charger dans la NameValueCollection ci-dessus.

Ensuite, nous définissons simplement une méthode “ApplyTheme” prenant en paramètre le nom du thème à affecter à l’application :

WpfThemes08

On utilise ici la propriété “Current” de la classe Application, nous permettant de récupérer l’instance courante de l’application et de lui affecter le dictionaire de ressources comme vu précédemment.

Création du ViewModel

Notre ViewModel va exposer la collection de thèmes du ThemesManager, ainsi qu’une RelayCommand (implémentation de ICommand) permettant de changer le thème à la volée :

WpfThemes09

Interface de la fenêtre principale

Après avoir défini notre ViewModel ci-dessus, pensez à l’affecter comme DataContext de votre Window. Vous pouvez ensuite créer votre interface (composée ici d’une combobox proposant la liste des thèmes) :

WpfThemes10

Ici, EventBehavior est une implémentation du pattern AttachedBehavior permettant d’éxecuter une commande par le binding lorsqu’un contrôle lève un évènement particulier. Pour bien comprendre ce pattern et cette implémentation, je vous conseil ce post de Thomas.

Il ne vous reste plus qu’à créer différents thèmes et à les déposer dans le dossier “Themes” à côté de l’exécutable de l’application. Vous aurez alors accès à vos différents thèmes au runtime et sans recompiler l’application !

WpfThemes11

Bien entendu, je n’ai pas créé ici de styles ou templates complexes, mais si vous en ajoutez à vos différents fichiers de thèmes, ceux-ci seront appliqués de la même façon : dynamiquement.

A bientôt Wink

Sources : WpfThemes.zip (93.42 kb)

Posted: May 03 2009, 14:18 by julienc | Comments (0) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: WPF | Général | CSharp

Add comment




biuquote
  • Comment
  • Preview
Loading

captcha

*