2010-12-01 16 views
8

Actualmente estoy trabajando en tener diccionarios de estilos y plantillas que pueda aplicar dinámicamente a mi aplicación. Antes de este "nuevo quería" comportamiento dinámico, que tenía varios diccionarios de recursos, uno para cada control de estilo, que se fusionó en el App.xaml: Recurso estático compartido en diccionarios fusionados

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="ColorsDictionary.xaml"/> 
      <ResourceDictionary Source="ControlsTemplatesDictionary.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

Ahora, me gustaría que mi solicitud para ser de estilo, así que decidí fusionar todos mis recursos previos en uno nuevo llamado "MyFirstTemplates" y agregar solo este diccionario a la App.xaml.

Nuevo diccionario "MyFirstTemplates.xaml":

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">" 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="ColorsDictionary.xaml"/> 
     <ResourceDictionary Source="ControlsTemplatesDictionary.xaml"/> 
    </ResourceDictionary.MergedDictionaries> 
</ResourceDictionary> 

Nueva App.xaml:

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="MyFirstTemplates.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
     <Style TargetType="{x:Type Window}"/> 
    </ResourceDictionary> 
</Application.Resources> 

Nota: El estilo por defecto para la ventanaes corregir un error de WPF 4, ver Adding a Merged Dictionary to a Merged Dictionary

Ahora que he hecho este cambio, no puedo usar un recurso de color de "ColorsDictionary.xaml" como StaticResource en "ControlsTemplateDictionary.xaml" más. Si cambio de nuevo a la fusión de estos archivos en la aplicación.xaml, todo funciona. Para que funcione, tengo que cambiar estos StaticResource por DynamicResource. ¿Tienes alguna idea de por qué esto ya no funciona?

Gracias :-)

Respuesta

7

Moviendo los diccionarios de App.xaml los recursos de cada diccionario no están en el árbol del otro recurso durante la carga de MyFirstTemplates.xaml. La configuración original primero cargó ColorsDictionary que estaba disponible a través de los recursos de la aplicación a ControlsTemplatesDictionary mientras se cargaba. En su nueva configuración, para que el recurso de color esté disponible en los recursos de la aplicación, debe cargarse a través de MyFirstTemplates, que a su vez requiere la carga de ambos diccionarios, lo que a su vez requiere acceso al recurso de color ... por lo que es una especie de un bucle infinito de referencias que no se puede resolver de forma estática. DynamicResource puede esperar hasta que todo esté cargado y luego acceder al color sin problemas.

Para solucionarlo, utilice Dynamic o combine ColorsDictionary directamente en ControlsTemplatesDictionary.

+0

Gracias por su conocimiento :-) –

2

Gran respuesta de John explicando por qué sucede esto. Entonces, el problema es que cuando se utilizan diccionarios fusionados dentro de un diccionario fusionado, los diccionarios internos no pueden "usar" entre sí como StaticResource.

soluciones básicas:

  • Uso DynamicResource
  • Usar sólo un único nivel de jerarquía de App.xaml cuando se utiliza StaticResource

Ambas soluciones tienen problemas. DynamicResource tiene un problema de rendimiento. La segunda solución te limita a la forma de organizar tus recursos XAML.

solución alternativa:

he creado un pequeño programa simple (siempre por debajo en GitHub) que funcionará como un evento de pre-construcción y combinar archivos XAML de una carpeta en un archivo .xaml larga. Bueno, necesitan estar con una extensión diferente (.txaml), de lo contrario se compilarán.

Esto permite estructurar carpetas de recursos y archivos como quiera, sin las limitaciones de WPF. StaticResource y el diseñador funcionarán siempre.

The code in GitHub contiene una solución simple que contiene el programa de fusión. Combina 2 carpetas en 2 archivos. Uno para los recursos de App.xaml y el otro para los recursos de Generic.xaml. Los archivos .xaml en un proyecto de "Controles" (También hay un proyecto "Principal").

Blog post explaining this

Cuestiones relacionadas