ResourceDictionary dans un assemblage séparé

245

J'ai des fichiers de dictionnaire de ressources (MenuTemplate.xaml, ButtonTemplate.xaml, etc.) que je souhaite utiliser dans plusieurs applications distinctes. Je pourrais les ajouter aux assemblys des applications, mais c'est mieux si je compile ces ressources dans un seul assemblage et que mes applications y font référence, non?

Une fois l'assembly de ressource créé, comment puis-je le référencer dans le fichier App.xaml de mes applications? Actuellement, j'utilise ResourceDictionary.MergedDictionaries pour fusionner les fichiers de dictionnaire individuels. Si je les ai dans un assemblage, comment puis-je les référencer dans xaml?

Gus Cavalcanti
la source
1
Cela peut être exagéré, mais vous voudrez peut-être préparer vos ressources pour l'exportation en utilisant la technique décrite ici: alexfeinberg.wordpress.com/2015/08/16/… . Le principal avantage de cette opération est d'éviter les problèmes de chargement de plusieurs versions de l'assembly de ressources dans le même domaine d'application.
user195275

Réponses:

353

Découvrez la syntaxe URI du pack . Vous voulez quelque chose comme ça:

<ResourceDictionary Source="pack://application:,,,/YourAssembly;component/Subfolder/YourResourceFile.xaml"/>
Kent Boogaart
la source
1
Que faire si YourAssembly n'est pas contenu dans le chemin de l'application?
SaneDeveloper
@Engineer Spock: alors le CLR ne le trouvera pas sans aide (rien à voir spécifiquement avec WPF). Ajoutez des chemins de sondage à votre app.config ou attachez-le AppDomain.AssemblyResolvepour l'aider à trouver l'assembly.
Kent Boogaart
1
Dois-je ajouter un chemin de sondage si le projet YourAssembly est au même niveau que le projet d'application qui doit référencer YourAssembly? Par exemple, C: \ Solution \ AppProject \ et C: \ Solution \ YourAssemblyProject \
SaneDeveloper
1
@EngineerSpock: il s'agit d'une question distincte, veuillez donc en ouvrir une.
Kent Boogaart
2
Cette réponse n'a aucun sens. Pour le suivre, il faut déjà savoir le faire!
user1040323
97

Un exemple, juste pour en faire une réponse de 15 secondes -

Supposons que vous ayez "styles.xaml" dans une bibliothèque WPF nommée "common" et que vous souhaitiez l'utiliser à partir de votre projet d'application principal:

  1. Ajouter une référence du projet principal au projet "commun"
  2. Votre app.xaml doit contenir:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/Common;component/styles.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

À votre santé

Hertzel Guinness
la source
2
Et comment rendre les ressources définies dans styles.xaml disponibles via la fenêtre Propriétés de Visual Studio 2010? Si je sélectionne un élément, puis cliquez sur Appliquer la ressource pour sa propriété d'arrière-plan, il n'affiche que SystemColors et non ceux définis dans styles.xaml. Mais si je tape moi-même le nom de la ressource en XAML, cela fonctionne, donc il est correctement référencé.
xr280xr
Je voulais juste ajouter que si vous faites référence au ResourceDictionary de UserControl, vous devez ajouter une référence à l'assembly aux deux endroits: dans UserControl et dans le projet de fenêtre principale. Sinon, vous obtiendrez l'erreur d'exécution.
Andrejs Gasilovs
16

DLL de ressources uniquement est une option pour vous. Mais ce n'est pas obligatoire, sauf si vous souhaitez modifier les ressources sans recompiler les applications. Avoir un seul fichier ResourceDictionary commun est également une option. Cela dépend de la fréquence à laquelle vous changez de ressources, etc.

<ResourceDictionary Source="pack://application:,,,/
     <MyAssembly>;component/<FolderStructureInAssembly>/<ResourceFile.xaml>"/>

MyAssembly - Juste le nom de l'assembly sans extension

FolderStructureInAssembly - Si vos ressources sont dans un répertoire, spécifiez la structure du dossier

Lorsque vous faites cela, il est préférable de connaître également siteOfOrigin .

WPF prend en charge deux autorités: application: /// et siteoforigin: ///. L'autorité application: /// identifie les fichiers de données d'application connus au moment de la compilation, y compris les fichiers de ressources et de contenu. L'autorité siteoforigin: /// identifie les fichiers du site d'origine. La portée de chaque autorité est illustrée dans la figure suivante.

entrez la description de l'image ici

CharithJ
la source
8

Pour UWP:

<ResourceDictionary Source="ms-appx:///##Namespace.External.Assembly##/##FOLDER##/##FILE##.xaml" />
Gianluca Demarinis
la source
4

Utilisation de XAML:

Si vous connaissez l'autre assemblystructure et souhaitez le code resourcesen c # , utilisez le code ci-dessous:

 ResourceDictionary dictionary = new ResourceDictionary();
 dictionary.Source = new Uri("pack://application:,,,/WpfControlLibrary1;Component/RD1.xaml", UriKind.Absolute);
 foreach (var item in dictionary.Values)
 {
    //operations
 }

Sortie: si nous voulons utiliser le ResourceDictionary RD1.xamlprojet WpfControlLibrary1dans le StackOverflowAppprojet.

Structure des projets :

Structure des projets

Dictionnaire de ressources: Dictionnaire de ressources

Sortie de code:

Production

PS: Tous les ResourceDictionaryfichiers doivent avoir Build Actioncomme ' Resource' ou ' Page'.

Utilisation de C #:

Si quelqu'un veut la solution en code purement c #, voyez ma solution.

Kylo Ren
la source