2010-12-01 44 views
8

Je travaille actuellement sur des dictionnaires de styles et de modèles que je peux appliquer dynamiquement à mon application. Avant cette « nouvelle voulait » un comportement dynamique, j'ai eu plusieurs dictionnaires de ressources, un pour chaque commande de style, que je fusionné dans le App.xaml: Ressource statique partagée dans les dictionnaires fusionnés

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

Maintenant, je voudrais que ma demande soit de style, J'ai donc décidé de fusionner toutes mes ressources précédentes en une nouvelle appelée "MyFirstTemplates" et d'ajouter seulement ce dictionnaire à l'App.xaml.

Nouveau dictionnaire "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> 

Nouveau App.xaml:

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

Note: Le style par défaut de la fenêtre est de corriger un bug de WPF 4, voir Adding a Merged Dictionary to a Merged Dictionary

Maintenant que j'ai fait ce changement, je ne peux pas utiliser une ressource de couleur de "ColorsDictionary.xaml" comme StaticResource plus dans "ControlsTemplateDictionary.xaml". Si je reviens à fusionner ces fichiers dans le fichier app.xaml, tout fonctionne. Pour le faire fonctionner, je dois changer ces StaticResource pour DynamicResource. Avez-vous une idée de pourquoi cela ne fonctionne plus?

Merci :-)

Répondre

7

En déplaçant les dictionnaires de App.xaml les ressources de chaque dictionnaire ne sont pas dans l'arborescence des ressources de l'autre lors du chargement de MyFirstTemplates.xaml. Votre configuration d'origine a d'abord chargé ColorsDictionary qui était ensuite disponible via les ressources de l'application à ControlsTemplatesDictionary pendant son chargement. Dans votre nouvelle configuration, pour que la ressource couleur soit disponible dans les ressources de l'application, elle doit être chargée via MyFirstTemplates, ce qui nécessite le chargement des deux dictionnaires, ce qui nécessite l'accès à la ressource de couleur ... donc c'est en quelque sorte une boucle infinie de références qui ne peuvent pas être résolues statiquement. DynamicResource peut attendre que tout soit chargé, puis accéder à la couleur sans problème.

Pour corriger, utilisez Dynamic ou fusionnez ColorsDictionary directement dans ControlsTemplatesDictionary.

+0

Merci pour votre perspicacité :-) –

2

Grande réponse de John expliquant pourquoi cela se produit. Le problème est donc que lorsque vous utilisez des dictionnaires fusionnés dans un dictionnaire fusionné, les dictionnaires internes ne peuvent pas "s'utiliser" comme StaticResource.

solutions de base:

  • Utilisez DynamicResource
  • Utilisez juste un seul niveau de la hiérarchie de App.xaml lors de l'utilisation StaticResource

Ces deux solutions ont des problèmes. DynamicResource a un problème de performance. La 2ème solution vous limite sur la façon dont vous organisez vos ressources XAML.

Autre solution:

J'ai créé un petit programme simple (ci-dessous à GitHub) qui se déroulera comme un événement pré-construction et de fusionner des fichiers XAML à partir d'un dossier dans un seul fichier long XAML. Eh bien, ils doivent être avec une extension différente (.txaml), sinon ils seront compilés.

Ceci permet de structurer les dossiers et fichiers de ressources comme bon vous semble, sans les limitations de WPF. StaticResource et le concepteur fonctionneront toujours.

The code in GitHub contient une solution simple qui contient le programme de fusion. Il fusionne 2 dossiers en 2 fichiers. Un pour les ressources App.xaml et l'autre pour les ressources Generic.xaml. Les fichiers .xaml dans un projet "Controls" (Il y a aussi le projet "Main").

Blog post explaining this