合并资源字典Merged Resource Dictionaries

Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) 资源支持合并资源字典功能。resources support a merged resource dictionary feature. 此功能提供一种方法,可在编译的 XAMLXAML 应用程序外部定义 WPFWPF 应用程序的资源部分。This feature provides a way to define the resources portion of a WPFWPF application outside of the compiled XAMLXAML application. 然后可以在应用程序之间共享资源,还可更方便地将资源隔离以进行本地化。Resources can then be shared across applications and are also more conveniently isolated for localization.

引入合并资源字典Introducing a Merged Resource Dictionary

在标记中,使用以下语法将合并资源字典引入页面:In markup, you use the following syntax to introduce a merged resource dictionary into a page:

<Page.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="myresourcedictionary.xaml"/>
      <ResourceDictionary Source="myresourcedictionary2.xaml"/>
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Page.Resources>

请注意,ResourceDictionary 元素没有 "X:Key"指令,资源集合中的所有项通常都需要此指令。Note that the ResourceDictionary element does not have an x:Key Directive, which is generally required for all items in a resource collection. MergedDictionaries 集合中的另一个 ResourceDictionary 引用是一个特殊情况,为此合并资源字典方案保留。But another ResourceDictionary reference within the MergedDictionaries collection is a special case, reserved for this merged resource dictionary scenario. 引入合并资源字典的 ResourceDictionary 不能包含X:Key 指令The ResourceDictionary that introduces a merged resource dictionary cannot have an x:Key Directive. 通常,MergedDictionaries 集合中的每个 ResourceDictionary 指定 Source 属性。Typically, each ResourceDictionary within the MergedDictionaries collection specifies a Source attribute. Source 的值应为一个统一资源标识符(URI),该资源标识符解析为要合并的资源文件的位置。The value of Source should be a uniform resource identifier (URI) that resolves to the location of the resources file to be merged. 该 URI 的目标必须是另一个 XAMLXAML 文件,其 ResourceDictionary 为其根元素。The destination of that URI must be another XAMLXAML file, with ResourceDictionary as its root element.

备注

在指定为合并字典的 ResourceDictionary 中定义资源是合法的,无论是指定 Source的替代方法,还是除了指定的源中包含的所有资源。It is legal to define resources within a ResourceDictionary that is specified as a merged dictionary, either as an alternative to specifying Source, or in addition to whatever resources are included from the specified source. 但是,这不是一种常见方案;合并字典的主要方案是从外部文件位置合并资源。However, this is not a common scenario; the main scenario for merged dictionaries is to merge resources from external file locations. 如果要在页的标记中指定资源,通常应在主 ResourceDictionary 中定义这些资源,而不应在合并字典中定义这些资源。If you want to specify resources within the markup for a page, you should typically define these in the main ResourceDictionary and not in the merged dictionaries.

合并字典的行为Merged Dictionary Behavior

合并字典中的资源占用资源查找范围中的一个位置,此范围恰好在它们合并到的主要资源字典中的范围之后。Resources in a merged dictionary occupy a location in the resource lookup scope that is just after the scope of the main resource dictionary they are merged into. 尽管任何字典中的资源键必须唯一,但一个资源键可在一组合并字典中多次存在。Although a resource key must be unique within any individual dictionary, a key can exist multiple times in a set of merged dictionaries. 在这种情况下,返回的资源将来自 MergedDictionaries 集合中按顺序找到的最后一个字典。In this case, the resource that is returned will come from the last dictionary found sequentially in the MergedDictionaries collection. 如果 MergedDictionaries 集合是在 XAMLXAML中定义的,则集合中合并字典的顺序就是标记中提供的元素的顺序。If the MergedDictionaries collection was defined in XAMLXAML, then the order of the merged dictionaries in the collection is the order of the elements as provided in the markup. 如果在主要字典和合并的字典中均定义了同一个键,则返回的资源将来自主要字典。If a key is defined in the primary dictionary and also in a dictionary that was merged, then the resource that is returned will come from the primary dictionary. 这些范围规则同等地适用于静态资源引用和动态资源引用。These scoping rules apply equally for both static resource references and dynamic resource references.

合并字典和代码Merged Dictionaries and Code

可通过代码将合并字典添加到 Resources 字典。Merged dictionaries can be added to a Resources dictionary through code. 默认情况下,对于任何 Resources 属性,最初为空 ResourceDictionary 都有默认值,初始为空 MergedDictionaries 集合属性。The default, initially empty ResourceDictionary that exists for any Resources property also has a default, initially empty MergedDictionaries collection property. 若要通过代码添加合并字典,可获取对所需主 ResourceDictionary的引用、获取其 MergedDictionaries 属性值,并对 MergedDictionaries中包含的泛型 Collection 调用 AddTo add a merged dictionary through code, you obtain a reference to the desired primary ResourceDictionary, get its MergedDictionaries property value, and call Add on the generic Collection that is contained in MergedDictionaries. 添加的对象必须是新的 ResourceDictionaryThe object you add must be a new ResourceDictionary. 在代码中,你不设置 Source 属性。In code, you do not set the Source property. 相反,您必须通过创建一个 ResourceDictionary 对象或加载一个对象来获取该对象。Instead, you must obtain a ResourceDictionary object by either creating one or loading one. 一种加载现有 ResourceDictionary 以便在具有 ResourceDictionary 根的现有 XAMLXAML 文件流上调用 XamlReader.Load 的方法,然后将 XamlReader.Load 返回值强制转换为 ResourceDictionaryOne way to load an existing ResourceDictionary to call XamlReader.Load on an existing XAMLXAML file stream that has a ResourceDictionary root, then casting the XamlReader.Load return value to ResourceDictionary.

合并资源字典 URIMerged Resource Dictionary URIs

对于如何包含合并资源字典,有几种方法可供您使用的统一资源标识符(URI)格式来指示。There are several techniques for how to include a merged resource dictionary, which are indicated by the uniform resource identifier (URI) format that you will use. 这些技术可概括地分为两类:作为项目的一部分编译的资源,和不作为项目的一部分编译的资源。Broadly speaking, these techniques can be divided into two categories: resources that are compiled as part of the project, and resources that are not compiled as part of the project.

对于作为项目的一部分编译的资源,可使用引用资源位置的相对路径。For resources that are compiled as part of the project, you can use a relative path that refers to the resource location. 相对路径会在编辑期间计算。The relative path is evaluated during compilation. 必须将资源作为“资源”生成操作定义为项目的一部分。Your resource must be defined as part of the project as a Resource build action. 如果将资源 .xaml 文件作为“资源”包括在项目中,则无需将资源文件复制到输出目录,因为资源已包括在编译的应用程序中。If you include a resource .xaml file in the project as Resource, you do not need to copy the resource file to the output directory, the resource is already included within the compiled application. 也可以使用“内容”生成操作,但必须将文件复制到输出目录,还需将相同路径关系中的资源文件部署到可执行文件。You can also use Content build action, but you must then copy the files to the output directory and also deploy the resource files in the same path relationship to the executable.

备注

不要使用“嵌入资源”生成操作。Do not use the Embedded Resource build action. WPFWPF 应用程序支持生成操作本身,但 Source 的解决不包含 ResourceManager,因此无法将单个资源与流分离。The build action itself is supported for WPFWPF applications, but the resolution of Source does not incorporate ResourceManager, and thus cannot separate the individual resource out of the stream. 你仍可以将嵌入的资源用于其他目的,只要你还使用 ResourceManager 来访问资源。You could still use Embedded Resource for other purposes so long as you also used ResourceManager to access the resources.

还有一种相关技术是使用指向 XAMLXAML 文件的 Pack URI,并将其作为“源”进行引用。A related technique is to use a Pack URI to a XAMLXAML file, and refer to it as Source. Pack URI 可启用对引用程序集的组件和其他技术的引用。Pack URI enables references to components of referenced assemblies and other techniques. 有关 Pack URI 的详细信息,请参阅 WPF 应用程序资源、内容和数据文件For more information on Pack URIs, see WPF Application Resource, Content, and Data Files.

对于不作为项目的一部分编译的资源,URI 将在运行时计算。For resources that are not compiled as part of the project, the URI is evaluated at run time. 可使用常见的 URI 传输(如 file: 或 http:)引用资源文件。You can use a common URI transport such as file: or http: to refer to the resource file. 使用非编译资源方法的缺点是:file: 访问需要额外部署步骤,并且 http: 访问意味着需访问 Internet 安全区域。The disadvantage of using the noncompiled resource approach is that file: access requires additional deployment steps, and http: access implies the Internet security zone.

重用合并字典Reusing Merged Dictionaries

可以在应用程序之间重复使用或共享合并资源字典,因为要合并的资源字典可以通过任何有效的统一资源标识符(URI)进行引用。You can reuse or share merged resource dictionaries between applications, because the resource dictionary to merge can be referenced through any valid uniform resource identifier (URI). 执行此操作的确切方式取决于应用程序部署策略和所遵循的应用程序模型。Exactly how you do this will depend on your application deployment strategy and which application model you follow. 前面提及的 Pack URI 策略提供了一种方法,通常可通过共享程序集引用在开发期间跨多个项目将合并资源作为源使用。The aforementioned Pack URI strategy provides a way to commonly source a merged resource across multiple projects during development by sharing an assembly reference. 在此方案中,资源仍由客户端分发,并且至少有一个应用程序必须部署引用的程序集。In this scenario the resources are still distributed by the client, and at least one of the applications must deploy the referenced assembly. 还有可能通过使用 http 协议的分布式 URI 引用合并资源。It is also possible to reference merged resources through a distributed URI that uses the http protocol.

另一种合并字典/应用程序部署的可能方案是将合并字典编写为本地应用程序文件或编写到共享存储。Writing merged dictionaries as local application files or to local shared storage is another possible merged dictionary / application deployment scenario.

本地化Localization

如果需要本地化的资源保留为松散的 XAMLXAML,并且隔离于将合并为主要字典的字典,则可单独本地化这些文件。If resources that need to be localized are isolated to dictionaries that are merged into primary dictionaries, and kept as loose XAMLXAML, these files can be localized separately. 这是本地化附属资源程序集的轻量级替代方法。This technique is a lightweight alternative to localizing the satellite resource assemblies. 有关详细信息,请参阅 WPF 全球化和本地化概述For details, see WPF Globalization and Localization Overview.

请参阅See also