ResourceDictionary em um assembly separado

245

Eu tenho arquivos de dicionário de recursos (MenuTemplate.xaml, ButtonTemplate.xaml, etc) que desejo usar em vários aplicativos separados. Eu poderia adicioná-los aos assemblies dos aplicativos, mas é melhor se eu compilar esses recursos em um único assembly e meus aplicativos fizerem referência, certo?

Após a montagem do recurso, como referenciá-lo no App.xaml dos meus aplicativos? Atualmente, uso ResourceDictionary.MergedDictionaries para mesclar os arquivos de dicionário individuais. Se eu os tiver em uma montagem, como posso referenciá-los no xaml?

Gus Cavalcanti
fonte
1
Isso pode ser um exagero, mas você pode querer preparar seus recursos para a Exportação usando a técnica descrita aqui: alexfeinberg.wordpress.com/2015/08/16/… . A principal vantagem de fazer isso é evitar problemas com várias versões do assembly de recursos sendo carregadas no mesmo domínio de aplicativo.
User195275

Respostas:

352

Confira a sintaxe do URI do pacote . Você quer algo assim:

<ResourceDictionary Source="pack://application:,,,/YourAssembly;component/Subfolder/YourResourceFile.xaml"/>
Kent Boogaart
fonte
1
E se YourAssembly não estiver contido no caminho do aplicativo?
SaneDeveloper 26/08
@ Engenheiro Spock: o CLR não o encontrará sem ajuda (nada especificamente a ver com o WPF). Adicione caminhos de análise ao seu app.config ou anexe-o AppDomain.AssemblyResolvepara ajudá-lo a encontrar a montagem.
Kent Boogaart
1
Preciso adicionar um caminho de análise se o projeto YourAssembly estiver no mesmo nível do projeto de aplicativo que precisa fazer referência ao YourAssembly? Por exemplo, C: \ Solution \ AppProject \ e C: \ Solution \ YourAssemblyProject \
SaneDeveloper 26/13
1
@ EngineerSpock: esta é uma pergunta separada, portanto, abra uma.
Kent Boogaart
2
Esta resposta não faz sentido. Para segui-lo já é necessário saber como fazê-lo!
user1040323
97

Um exemplo, apenas para tornar isso uma resposta de 15 segundos -

Digamos que você tenha "styles.xaml" em uma biblioteca WPF denominada "common" e deseje usá-lo no seu projeto principal de aplicativo:

  1. Adicione uma referência do projeto principal ao projeto "comum"
  2. Seu app.xaml deve conter:

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

Felicidades

Hertzel Guinness
fonte
2
E então, como você disponibiliza os recursos definidos em styles.xaml através da janela Propriedades do Visual Studio 2010? Se eu selecionar um elemento e clicar em Aplicar Recurso para a propriedade Background, ele mostrará apenas SystemColors e não aqueles definidos em styles.xaml. Mas, se eu mesmo digitar o nome do recurso no XAML, ele funcionará, portanto será corretamente referenciado.
Xr280xr
Só queria acrescentar que, se você referenciar o ResourceDictionary do UserControl, precisará adicionar uma referência ao assembly nos dois locais: no UserControl e no projeto da janela principal. Caso contrário, você receberá o erro de tempo de execução.
Andrejs Gasilovs
16

DLL apenas de recurso é uma opção para você. Mas não é necessário necessariamente, a menos que você deseje modificar recursos sem recompilar aplicativos. Ter apenas um arquivo ResourceDictionary comum também é uma opção. Depende da frequência com que você altera recursos e etc.

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

MyAssembly - Apenas o nome do assembly sem extensão

FolderStructureInAssembly - Se seus recursos estiverem em um grupo, especifique a estrutura da pasta

Quando você está fazendo isso, é melhor conhecer também o siteOfOrigin .

O WPF suporta duas autoridades: application: /// e siteoforigin: ///. A autoridade application: /// identifica arquivos de dados do aplicativo que são conhecidos no momento da compilação, incluindo arquivos de recursos e conteúdo. A autoridade siteoforigin: /// identifica os arquivos do site de origem. O escopo de cada autoridade é mostrado na figura a seguir.

insira a descrição da imagem aqui

CharithJ
fonte
8

Para UWP:

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

Usando XAML:

Se você conhecer a outra assemblyestrutura e quer que o resourcesno c # código, em seguida, usar o código abaixo:

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

Saída: se queremos usar o ResourceDictionary RD1.xamlProject WpfControlLibrary1no StackOverflowAppprojeto.

Estrutura dos Projetos :

Estrutura dos Projetos

Dicionário de Recursos: Dicionário de Recursos

Saída de código:

Resultado

PS: Todos os ResourceDictionaryarquivos devem ter Build Actioncomo ' Resource' ou ' Page'.

Usando c #:

Se alguém quiser a solução em código c #, então veja esta minha solução.

Kylo Ren
fonte