2009-05-10 5 views
10

WPF permite que una biblioteca de control proporcione diferentes diccionarios de recursos para diferentes temas del sistema, permitiendo esencialmente que una aplicación coincida con el tema visual seleccionado del sistema operativo (Aero, Luna, etc.).¿Se pueden usar los temas de WPF para incluir varias máscaras para una aplicación que se puede cambiar en tiempo de ejecución?

Me pregunto si puedo incluir varios diccionarios de recursos de tema con mi aplicación y utilizar algún soporte de tema existente dentro del marco. Esto debería funcionar para mis propios nombres de tema, e idealmente permitirle al usuario cambiar el tema y, por lo tanto, la apariencia despellejada de la aplicación en tiempo de ejecución. Incluso si esto fuera solo una configuración, aún podría ser interesante.

Respuesta

11

Aquí hay un fragmento de código que utilicé en mi aplicación que los aceptó. En este ejemplo, tengo dos temas (XP predeterminado y clásico). Los recursos del tema se almacenan en DefaultTheme.xaml y ClassicTheme.xaml, respectivamente.

Este es el código predeterminado en mi 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> 

Luego, en el código detrás de la App.xaml tengo el siguiente método para que puedan cambiar el tema. Básicamente, lo que haces es borrar los diccionarios de recursos y luego volver a cargar el diccionario con el nuevo 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); 
    } 

Lo que también tendrá que tener en cuenta con este enfoque es que los estilos que utilizan un tema necesitarán tener un recurso dinámico. Por ejemplo:

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

excelente respuesta, lo he implementado, me preguntaba cómo usaría esto para cambiar las imágenes de los botones vinculados. He hecho una pregunta aquí: http://stackoverflow.com/questions/39795317/how-do-i-dynamically-change-which-resource-folder-i-get-an-image-from – AidanO

3

No conozco una forma de hacerlo en el marco, pero puede hacerlo si aplica todos los controles que pueda cambiar usted mismo.

La teoría es hacer que el estilo sea DynamicResource y luego cargar el ResourcesDictionary según la configuración de los usuarios para el estilo diferente.

Here es un artículo que tiene un ejemplo.

Cuestiones relacionadas