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
输出:如果我们想使用ResourceDictionary
RD1.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?