2009-05-10 9 views
10

WPF permet à une bibliothèque de contrôles de fournir différents dictionnaires de ressources pour différents thèmes système, permettant essentiellement à une application de correspondre au thème visuel sélectionné du système d'exploitation (Aero, Luna, etc.). Je me demande si je peux inclure plusieurs dictionnaires de ressources de thème avec mon application et utiliser un support de thème existant dans le cadre. Cela devrait fonctionner pour mes propres noms de thème, et idéalement permettre à l'utilisateur de changer le thème et donc l'aspect dépouillé de l'application lors de l'exécution. Même s'il ne s'agissait que d'un réglage de configuration, cela pourrait être intéressant.Les thèmes WPF peuvent-ils être utilisés pour inclure plusieurs skins pour une application qui peut être modifiée lors de l'exécution?

Répondre

11

Voici un extrait de code que j'ai utilisé dans mon application qui prenait en charge les thèmes. Dans cet exemple, j'ai deux thèmes (Default et Classic XP). Les ressources de thème sont stockées respectivement dans DefaultTheme.xaml et ClassicTheme.xaml.

C'est le code par défaut dans mon App.xaml

<Application ...> 
    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="ArtworkResources.xaml" /> 
       <ResourceDictionary Source="DefaultTheme.xaml" /> 
      </ResourceDictionary.MergedDictionaries> 

      <Style x:Key="SwooshButton" TargetType="ButtonBase"> 
       <!-- style setters --> 
      </Style> 

      <!-- more global styles --> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

Puis dans le code derrière la App.xaml je la méthode suivante pour permettre de changer le thème. Fondamentalement, ce que vous faites est effacer les dictionnaires de ressources, puis recharger le dictionnaire avec le nouveau thème.

private Themes _currentTheme = Themes.Default; 
    public Themes CurrentTheme 
    { 
     get { return _currentTheme; } 
     set { _currentTheme = value; } 
    } 

    public void ChangeTheme(Themes theme) 
    { 
     if (theme != _currentTheme) 
     { 
      _currentTheme = theme; 
      switch (theme) 
      { 
       default: 
       case Themes.Default: 
        this.Resources.MergedDictionaries.Clear(); 
        AddResourceDictionary("ArtworkResources.xaml"); 
        AddResourceDictionary("DefaultTheme.xaml"); 
        break; 
       case Themes.Classic: 
        this.Resources.MergedDictionaries.Clear(); 
        AddResourceDictionary("ArtworkResources.xaml"); 
        AddResourceDictionary("ClassicTheme.xaml"); 
        break; 
      } 
     } 
    } 

    void AddResourceDictionary(string source) 
    { 
     ResourceDictionary resourceDictionary = Application.LoadComponent(new Uri(source, UriKind.Relative)) as ResourceDictionary; 
     this.Resources.MergedDictionaries.Add(resourceDictionary); 
    } 

Ce que vous aurez également besoin de garder à l'esprit cette approche est que tous les styles qui utilisent un thème devront avoir une ressource dynamique. Par exemple:

<Window Background="{DynamicResource AppBackgroundColor}" /> 
+0

bonne réponse, j'ai implémenté cela, je me demandais comment vous utiliseriez cela pour changer les images de boutons liés. J'ai posé une question ici: http://stackoverflow.com/questions/39795317/how-do-i-dynamically-change-which-resource-folder-i-get-an-image-from – AidanO

3

Je ne connais pas de façon de faire cela dans le cadre, mais vous pouvez le faire si vous stylisez chaque contrôle qui peut changer vous-même.

La théorie est de faire un style DynamicResource puis de charger le ResourcesDictionary en fonction de la configuration des utilisateurs pour le style différent.

Here est un article qui a un exemple.

Questions connexes