合并资源字典 (WPF .NET)
Windows Presentation Foundation (WPF) 资源支持合并资源字典功能。 此功能提供了一种方法,用于在已编译的 XAML 应用程序外部定义 WPF 应用程序的资源部分。 然后可以在应用程序之间共享资源,还可更方便地将资源隔离以进行本地化。
创建合并字典
在标记中,使用以下语法将合并资源字典引入页面:
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="myresourcedictionary.xaml"/>
<ResourceDictionary Source="myresourcedictionary2.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
ResourceDictionary 元素不具有 x:Key 指令,通常该指令对于资源集合中的所有项是必需的。 但 MergedDictionaries 集合中的另一个 ResourceDictionary
引用是一个特殊情况,是为此合并资源字典方案预留的。 进一步讲,引入合并资源字典的 ResourceDictionary
不能有 x:Key 指令。
通常情况下,MergedDictionaries 集合中的每个 ResourceDictionary 都指定一个 Source 属性。 Source
的值应是解析到待合并资源文件的位置的统一资源标识符 (URI)。 该 URI 的目标必须是另一个 XAML 文件,以 ResourceDictionary
作为其根元素。
注意
在指定为合并字典的 ResourceDictionary 内定义资源是合法的,可将此作为指定 Source 的替代方法,或作为指定源中包括的任何资源的补充。 但是,这不是一种常见的方案。 合并字典的主要方案是从外部文件位置合并资源。 如果想要在标记内为某一页指定资源,请在主要 ResourceDictionary
中(而不是合并字典中)定义这些资源。
合并字典行为
合并字典中的资源会占用资源查找范围中的一个位置,此范围恰好在它们合并到的主要资源字典中的范围之后。 尽管任何字典中的资源键必须唯一,但一个资源键可在一组合并字典中多次存在。 在这种情况下,返回的资源将来自在 MergedDictionaries 集合中按顺序找到的最后一个字典。 如果在 XAML 中定义了 MergedDictionaries 集合,则合并字典在此集合中的顺序即是标记中提供的元素顺序。 如果在主要字典和合并的字典中均定义了同一个键,则返回的资源将来自主要字典。 这些范围规则同等地适用于静态资源引用和动态资源引用。
合并字典和代码
可通过代码将合并字典添加到 Resources
字典。 对于任何 Resources
属性存在的初始为空的默认 ResourceDictionary 也有初始为空的默认 MergedDictionaries 集合属性。 若要通过代码添加合并字典,需要获取对所需主要 ResourceDictionary
的引用、获取其 MergedDictionaries
属性值,并对 MergedDictionaries
中包含的泛型 Collection
调用 Add
。 添加的对象必须是新的 ResourceDictionary
。
在代码中,不要设置 Source 属性。 相反,必须通过创建或加载来获得 ResourceDictionary
对象。 加载现有 ResourceDictionary
的一种方法是对具有 ResourceDictionary
根的现有 XAML 文件流调用 XamlReader.Load,然后将返回值强制转换为 ResourceDictionary
。
合并字典 URI
可以通过几种技术来包括合并资源字典,具体视你所使用的统一资源标识符 (URI) 格式而定。 宽泛地讲,这些技术可以分为两个类别:作为项目的一部分编译的资源,以及未作为项目的一部分编译的资源。
对于作为项目的一部分编译的资源,可使用引用资源位置的相对路径。 相对路径会在编辑期间计算。 必须将资源作为“资源”生成操作定义为项目的一部分。 如果将资源 .xaml 文件作为“资源”包括在项目中,则无需将资源文件复制到输出目录,此资源已包括在已编译的应用程序中。 也可以使用“内容”生成操作,但随后必须将文件复制到输出目录,还必须将相同路径关系中的资源文件部署到可执行文件。
注意
请勿使用“嵌入资源”生成操作。 WPF 应用程序支持该生成操作本身,但 Source 的解析不会纳入 ResourceManager,因此不能将单个资源从流中分离出来。 只要你还使用了 ResourceManager 来访问资源,那么你仍然可以将“嵌入资源”用于其他目的。
一种相关技术是使用指向 XAML 文件的 Pack URI,并将它作为“源”进行引用。 Pack URI 支持对引用程序集的组件和其他技术的引用。 有关 Pack URI 的详细信息,请参阅 WPF 应用程序资源、内容和数据文件。
对于未作为项目的一部分编译的资源,URI 是在运行时计算的。 可以使用常见的 URI 传输(例如 file: 或 http:)来引用资源文件。 使用非编译的资源方法的缺点在于 file: 访问需要额外的部署步骤,并且 http: 访问意味着需要访问 Internet 安全区域。
重用合并字典
可以重复使用或在应用程序之间共享合并资源字典,因为可以通过任何有效的统一资源标识符 (URI) 引用要合并的资源字典。 执行此操作的确切方式取决于应用程序部署策略以及所遵循的应用程序模型。 前面提及的 Pack URI 策略提供了一种方法,通常用于通过共享程序集引用在开发期间跨多个项目将合并资源作为源使用。 在此方案中,资源仍由客户端分发,并且至少有一个应用程序必须部署引用的程序集。 还可以通过使用 http: 协议的分布式 URI 引用合并资源。
另一种合并字典和应用程序部署的可能方案是将合并字典编写为本地应用程序文件或编写到本地共享存储。
本地化
如果需要本地化的资源独立于将合并为主要字典的字典,并且保留为宽松 XAML,则可以单独本地化这些文件。 这是本地化附属资源程序集的轻量级替代方法。 有关详细信息,请参阅 WPF 全球化和本地化概述。