ResourceDictionary 在单独的程序集中

Posted

技术标签:

【中文标题】ResourceDictionary 在单独的程序集中【英文标题】:ResourceDictionary in a separate assembly 【发布时间】:2010-09-25 04:21:33 【问题描述】:

我有想要在多个单独的应用程序中使用的资源字典文件(MenuTemplate.xaml、ButtonTemplate.xaml 等)。我可以将它们添加到应用程序的程序集中,但最好将这些资源编译到一个程序集中并让我的应用程序引用它,对吗?

构建资源程序集后,如何在我的应用程序的 App.xaml 中引用它?目前我使用 ResourceDictionary.MergedDictionaries 来合并各个字典文件。如果我将它们放在程序集中,如何在 xaml 中引用它们?

【问题讨论】:

这可能有点矫枉过正,但您可能希望使用此处描述的技术为导出准备资源:alexfeinberg.wordpress.com/2015/08/16/…。这样做的主要优点是防止资源程序集的多个版本被加载到同一个 appdomain 时出现问题。 【参考方案1】:

查看pack URI syntax。你想要这样的东西:

<ResourceDictionary Source="pack://application:,,,/YourAssembly;component/Subfolder/YourResourceFile.xaml"/>

【讨论】:

如果 YourAssembly 不包含在应用程序路径中怎么办? @Engineer Spock:如果没有帮助,CLR 将找不到它(与 WPF 无关)。将探测路径添加到您的 app.config,或附加到 AppDomain.AssemblyResolve 以帮助它找到程序集。 如果YourAssembly项目与需要引用YourAssembly的应用项目处于同一级别,是否需要添加探测路径?例如,C:\Solution\AppProject\ 和 C:\Solution\YourAssemblyProject\ @EngineerSpock:这是一个单独的问题,所以请打开一个。 这个答案没有意义。为了遵循它,一个人已经需要知道如何去做!【参考方案2】:

举个例子,只是为了让这成为一个 15 秒的答案 -

假设您在名为“common”的 WPF 库中有“styles.xaml”,并且您想在主应用程序项目中使用它:

    添加从主项目到“普通”项目的引用 您的 app.xaml 应包含:

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

【讨论】:

那么如何通过 Visual Studio 2010 属性窗口使 styles.xaml 中定义的资源可用?如果我选择一个元素,然后单击它的背景属性的应用资源,它只显示 SystemColors 而不是那些在 styles.xaml 中定义的。但是,如果我自己在 XAML 中键入资源名称,它就可以工作,因此它被正确引用。 只是想补充一点,如果您从 UserControl 引用 ResourceDictionary,那么您需要在两个地方添加对程序集的引用:在 UserControl 和主窗口项目中。否则你会得到运行时错误。【参考方案3】:

我正在使用 .NET 4.5,但无法正常工作...我使用的是 WPF 自定义控件库。这最终对我有用......

<ResourceDictionary Source="/MyAssembly;component/mytheme.xaml" />

来源: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/11a42336-8d87-4656-91a3-275413d3cc19

【讨论】:

【参考方案4】:

仅资源 DLL 是您的一个选择。但除非您想在不重新编译应用程序的情况下修改资源,否则不一定需要。只有一个通用的 ResourceDictionary 文件也是一种选择。这取决于您更改资源等的频率。

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

MyAssembly - 只是没有扩展名的程序集名称

FolderStructureInAssembly - 如果您的资源位于文件夹中,请指定文件夹结构

当您这样做时,最好同时注意 siteOfOrigin

WPF 支持两种权限:application:/// 和 siteoforigin:///。 application:/// 权限标识应用程序数据文件 在编译时是已知的,包括资源和内容文件。这 siteoforigin:/// 权限标识原始文件的站点。范围 各权限如下图所示。

【讨论】:

【参考方案5】:

对于 UWP:

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

【讨论】:

【参考方案6】:

使用 XAML:

如果您知道另一个assembly 结构并希望在c# 代码中使用resources,请使用以下代码:

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

输出:如果我们想使用ResourceDictionaryRD1.xaml项目WpfControlLibrary1***App项目。

项目结构

资源字典:

代码输出:

PS:所有ResourceDictionary 文件的Build Action 应为“Resource”或“Page”。

使用 C#:

如果有人想要纯 c# 代码 中的解决方案,请查看我的this solution.

【讨论】:

以上是关于ResourceDictionary 在单独的程序集中的主要内容,如果未能解决你的问题,请参考以下文章

从 Catel WPF UserControl 中的 ResourceDictionary 中绑定

错误:“ResourceDictionary”根元素需要 x:Class 特性来支持 XAML 文件中的事件处理程序。请移除 MouseLeftButtonDown 事件的事件处理程序.

WinUI XAML:使用来自另一个项目的 ResourceDictionary

资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件

ResourceDictionary 中的 IValueConverter

(WPF) 如何从 ResourceDictionary 将 sys:Double 的值设置为 SystemFonts.MessageFontSize?