2009-05-10 7 views
10

WPF consente a una libreria di controlli di fornire dizionari di risorse differenti per diversi temi di sistema, consentendo essenzialmente a un'applicazione di corrispondere al tema visivo selezionato del sistema operativo (Aero, Luna, ecc.).È possibile utilizzare temi WPF per includere più skin per un'applicazione che può essere modificata in fase di runtime?

Mi chiedo se posso includere più dizionari di risorse tema con la mia applicazione e utilizzare alcuni supporti di temi esistenti all'interno del framework. Questo dovrebbe funzionare per i miei nomi dei temi e consentire idealmente all'utente di cambiare il tema e quindi l'aspetto della pelle dell'applicazione in fase di esecuzione. Anche se questa fosse solo un'impostazione di configurazione, potrebbe comunque essere interessante.

risposta

11

Ecco uno snippet di codice che ho utilizzato nella mia applicazione che supportava il tema. In questo esempio, ho due temi (predefinito e classico XP). Le risorse del tema sono memorizzate rispettivamente in DefaultTheme.xaml e ClassicTheme.xaml.

Questo è il codice predefinito nel mio 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> 

Poi nel codice dietro della App.xaml Ho il seguente metodo per consentire di cambiare il tema. Fondamentalmente, quello che fai è cancellare i dizionari delle risorse e quindi ricaricare il dizionario con il nuovo tema.

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); 
    } 

Ciò che dovrete anche tenere a mente con questo approccio è che tutti gli stili che utilizzano un tema dovranno avere una risorsa dinamica. Ad esempio:

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

ottima risposta, ho implementato questo, mi chiedevo come si userebbe questo per cambiare le immagini dei pulsanti associati. Ho posto una domanda qui: http://stackoverflow.com/questions/39795317/how-do-i-dynamically-change-which-resource-folder-i-get-an-image-from – AidanO

3

Non conosco un modo per farlo nel framework, ma puoi farlo se stili ogni controllo che può cambiare te stesso.

La teoria è di rendere lo stile un DynamicResource e quindi caricare lo ResourcesDictionary in base alla configurazione degli utenti per il diverso stile.

Here è un articolo che ha un esempio.

Problemi correlati