XAML 定义应用的 UI,并且 XAML 也可以定义 XAML 中的资源。资源通常是对你希望多次使用的某些对象的定义。你要为 XAML 资源定义一个键,以供将来引用,该键的作用类似于资源的名称。你可以在整个应用中或从应用中的任意 XAML 页面引用资源。Windows 运行时 XAML 具有一个 ResourceDictionary 元素,你可以在其中定义你的资源。然后可使用 StaticResource 标记扩展或 ThemeResource 标记扩展来引用你的资源。
你最希望声明为 XAML 资源的 XAML 元素包括 Style、ControlTemplate、动画组件和 Brush 子类。我们在此处介绍了如何定义一个 ResourceDictionary 和键控资源,以及 XAML 资源与你在应用或应用包中定义的其他资源之间的关系。我们还介绍了资源字典高级功能,例如 MergedDictionaries 和 ThemeDictionaries。
先决条件
我们假设你理解 XAML 标记并已阅读 XAML 概述。
XAML 资源必须可共享
对于存在于 ResourceDictionary 中的对象,该对象必须“可共享”。
可共享是必要的,因为在构造以及在运行时使用应用的对象树时,对象不能存在于树中的多个位置。就内部而言,在请求所有 XAML 资源时,资源系统会为在资源的对象图中使用的资源值创建副本。
通常,ResourceDictionary 和 Windows 运行时 XAML 支持将下列对象用于共享:
- 样式和模板(从 FrameworkTemplate 派生的 Style 和类)
- 画笔和颜色(从 Brush 派生的类和 Color 值)
- 动画类型,包括 Storyboard
- 转换(从 GeneralTransform 派生的类)
- Matrix 和 Matrix3D
- Point 值
- 其他与 UI 相关的某些结构,例如 Thickness 和 CornerRadius
- XAML 固有数据类型
此外,如果遵循必要的实现模式,则可将自定义类型用作可共享资源。在支持代码(或所含运行时组件)中定义这些类,然后在 XAML 中将其实例化为资源。示例包括对象数据源和用于数据绑定的 IValueConverter 实现。
自定义类型必须包含默认构造函数,因为 XAML 分析程序须借助该构造函数对类进行实例化。用作资源的自定义类型不能包含其继承中的 UIElement 类,因为 UIElement 无法共享(而只能用于表示运行时应用的对象图中某一位置的一个 UI 元素)。
资源的键
必须为 ResourceDictionary 内的每项定义一个键。从编程意义上讲,ResourceDictionary 实际上是一个字典。通常可使用 x:Key 特性为 XAML 资源定义键。 可以作为 XAML 资源的对象有很多种,而这些对象不共享任何共用 Windows 运行时属性。因此,若要将可能存在的多种资源放到一个资源字典中,应通过 XAML 语言对 x:Key 特性进行全局定义,该特性可以合法地应用于字典中的任何 XAML 对象元素。
x:Key 成为字典项的键,而 XAML 中的其他值所定义的对象则作为该项的值。
Windows 运行时 XAML 的资源必须使用字符串作为其键名称。具体而言,该字符串必须遵循 XamlName 语法的规则。如需有关信息,请参见“x:Key 特性”参考页面上的“XamlName 语法”一节。
如果将一项包含在 ResourceDictionary 中,并且该项没有一个适用的键,在应用尝试查找资源项时将发生一个 XAML 分析错误。如果复制一个键,则会导致分析错误。如果 XAML 中有资源定义或资源引用问题,Microsoft Visual Studio 和它的 XAML 设计界面常常能提供设计时反馈。但是,如果 XAML 设计人员不能提供警告,应用在运行时尝试加载 XAML 时,XAML 资源定义问题可能报告为错误或异常。
控件模板和样式的隐式键
控件模板和带 TargetType 属性的 Style 元素均属于特殊情况,因为它以 XAML 资源的形式存在时不需要 x:Key 特性值。对于这些类型而言,资源的键为隐式键。该隐式键的值基于在模板或样式中声明的字符串形式的 TargetType 值,并且在运行时 XAML 控件逻辑将使用该键,用于隐式查找应用于特殊控件的样式或模板。例如,包含TargetType="Button"
的 Style 可以是应用中所有 Button 控件的隐式样式,它在资源的定义中或来自每个 Button 的StaticResource 引用中无需使用键。有关隐式样式及其工作方式的详细信息,请参阅快速入门:控件模板。
情节提要资源
Storyboard 资源是另一种特殊情况,其中 Storyboard 可以在不具有 x:Key 值的情况下存在于的ResourceDictionary 中,但前提是它具有 x:Name 值。将 Storyboard 放置在 ResourceDictionary 中的操作通常不可重用,因为其中的动画已指向特定属性。但是,ResourceDictionary 仅仅是一个便捷 XAML 容器,可用于在其中放置各种 Storyboard 元素。最终,你将按名称引用 Storyboard 实例,并调用其 Begin 方法。通常通过代码隐藏完成此操作以响应 Loaded 等事件,或绑定到用户启动的事件。有关详细信息,请参阅情节提要动画。
直接和应用资源
对于包含 ResourceDictionary 节点并可在其中定义 XAML 资源的典型应用,其包含以下两种属性:FrameworkElement.Resources 和 Application.Resources。
FrameworkElement.Resources 提供直接资源。直接资源有时也称为页面资源。在 XAML 中,你可以使用直接引用技术,从连接到相同对象树的任何对象的 FrameworkElement.Resources 中引用 XAML 资源。这基本上意味着从相同的 XAML 页面引用,因为通常都是在 XAML 页面的根元素上定义 FrameworkElement.Resources 值,在这里页面内可能存在的所有 XAML 元素都可以找到它。
Application.Resources 提供应用级资源。无论加载哪个页面或其他 UI 作为应用当前的Window.Content,Application.Resources 定义的资源都可用。如果将不同页面加载到 Window.Content 中以支持导航,并且希望避免在每个页面中复制相同的资源,则在应用级指定资源会很有用。另外,如果为使稍后加载的页面能找到 ResourceDictionary 而在运行时向其添加键/值对(资源),则应用范围会提供一个位置,以供在应用的生存期中持久保存这些资源。
可能存在资源的第三个位置是在控件的默认样式中,它与控件一起封装。此位置仅用于查找使用控件的DefaultStyleKey 值作为键的资源。
注意 不要将 ResourceDictionary 相关的概念与“资源”构建操作、资源 (.resw) 文件或在创建生成应用包的代码项目上下文中探讨的其他“资源”相混淆。有关应用资源概念的详细信息,请参阅定义应用资源和如何为本地化做准备。
从 XAML 引用资源
在 XAML 中,你可以使用 StaticResource 标记扩展或 ThemeResource 标记扩展从 ResourceDictionary 引用现有 XAML 资源。在本文档中,这些统称为 XAML 资源引用。要通过标记扩展使用 XAML 资源引用,你必须始终使用属性语法引用你设置的属性。
以下是一些示例 XAML。若要设置 Button 的 Background 属性值以使用名为 fadeBrush
的静态资源,你必须先使用键声明资源,然后才能按键引用该资源。
<ResourceDictionary>
...
<LinearGradientBrush x:Key="fadeBrush">
<GradientStop Color="Red" Offset="0"/>
<GradientStop Color="Gray" Offset="1"/>
</LinearGradientBrush>
</ResourceDictionary>
...
<!--XAML within a UserControl or some other root container tag that defines app UI-->
<Button Background="{StaticResource fadeBrush}" .../>
在前面的示例中,两部分 XAML 可能甚至未在同一个 XAML 文件中。ResourceDictionary 可在Application.Resources 中的主题字典文件或合并字典文件中定义。
你可使用 XAML 属性语法来执行 XAML 资源引用,即使你设置的属性通常需要在 XAML 中使用属性元素也是如此。例如,这是一种等效的属性元素用法,该用法显示了以内联方式而非作为 ResourceDictionary 资源定义的LinearGradientBrush。
<Button>
<Button.Background>
<LinearGradientBrush>
<GradientStop Color="Red" Offset="0"/>
<GradientStop Color="Gray" Offset="1"/>
</LinearGradientBrush>
</Button.Background>
</Button>
针对 XAML 资源引用的查找行为
查找行为这一术语用于表示 XAML 资源系统如何尝试查找 XAML 资源。此查找适用于在应用 XAML 的某处被引用为 XAML 资源引用的键。资源系统具有可预测行为,它将为此类行为根据作用域检查是否存在资源。如果在初始作用域中未找到资源,该作用域将展开。将在应用或系统可能定义了 XAML 资源的位置和作用域上继续查找行为。如果所有可能的资源查找尝试均失败,通常会导致错误。通常可以在开发过程中消除这些错误。
针对 XAML 资源引用的查找行为首先从实际应用引用的对象以及它自己的 Resources 属性开始。如果存在一个ResourceDictionary,则会检查该 ResourceDictionary 以查看其中是否存在具有所请求键的项。该第一级查找很少包含相关信息,因为你通常不会在同一个对象上定义某个资源然后引用该资源。 实际上,Resources 属性通常不存在。你几乎可以在 XAML 中的任何位置进行 XAML 资源引用,而是仅限于在 FrameworkElement 子类的属性中。
查找序列然后检查应用的运行时对象树中的下一个父对象。如果存在一个 FrameworkElement.Resources 并且它持有一个 ResourceDictionary,将请求具有指定键字符串的字典项。如果找到资源,查找序列就会停止,并将该对象提供到执行引用的位置。否则,查找行为会向对象树根方向前进到下一个父级对象。此查找会继续递归前进,直至到达 XAML 的根元素,从而完成对所有可能直接资源位置的搜索。
注意 一种常见的做法是在页面的根级别定义所有直接资源,以利用该资源查找行为并将其用作 XAML 标记样式的一个惯例。
如果未在直接资源中找到所请求的资源,下一个查找步骤是检查 Application.Resources 属性。Application.Resources 是放置被应用导航结构中多个页面引用的任何应用特定资源的最佳位置。
在引用查找中,控件模板有另一个可能的位置:主题字典。主题字典是单个 XAML 文件,它使用一个ResourceDictionary 元素作为其根。主题字典可能是来自 Application.Resources 的一个合并字典。主题字典也可能是一个特定于控件的主题字典,用于模板化的自定义控件。
最后,还有一种针对平台资源的资源查找。平台资源包括为每个系统 UI 主题定义的控件模板,以及用于定义你在 Windows 运行时应用中为所有 UI 控件使用的默认外观的控件模板。平台资源还包括与系统范围内的外观和主题相关的一组已命名资源。从技术上来说,这些资源是 MergedDictionaries 项,因此在加载应用之后可用于从 XAML 或代码中查找。例如,系统主题资源包括一个名为 "SystemColorWindowTextColor" 的资源,该资源提供一个 Color 定义以使应用文本颜色与系统窗口的文本颜色(来自操作系统和用户首选项)相匹配。应用的其他 XAML 样式可以引用该样式,或者你的代码可以获取资源查找值(并将该值强制转换为示例中的 Color)。
有关可用于使用 XAML 的 Windows 应用商店应用的特定于主题和系统资源的详细信息和列表,请参阅 XAML 主题资源引用。
如果请求的键仍未在这其中任何位置中找到,会发生 XAML 分析错误/异常。某些情况下,XAML 分析异常可能是 XAML 标记编译操作或 XAML 设计环境未检测到的运行时异常。
根据针对资源字典的分层查找行为,你可特意定义多个资源项,每个资源项使用相同的字符串值作为键,只要将每个资源定义在不同的级别上即可。换言之,尽管键在任何给定的 ResourceDictionary 中必须是唯一的,但该唯一性要求不会扩展到整个查找行为序列。在查找过程中,只有成功检索到的首个此类对象会用于 XAML 资源引用,随即查找便会停止。你可以利用此行为在应用 XAML 内的各个位置通过键请求相同的 XAML 资源,但会取回不同的资源,具体取决于进行 XAML 资源引用的范围以及特殊查找的行为方式。
合并的资源字典
合并的资源字典使你能够引用一个外部文件来声明资源字典的内容,使用外部定义的资源来补充在 Resources 属性中找到的资源。合并的资源字典的使用修改了资源字典的两个特征:查找序列和一个范围内的键唯一性需求。
要声明合并的资源字典,可以向一个现有 ResourceDictionary 元素的 MergedDictionaries 属性添加一个属性元素。你可以为 FrameworkElement.Resources 或 Application.Resources 属性添加MergedDictionaries(但合并到Application.Resources 中是更典型的做法)。
你必须显式地将 ResourceDictionary 声明为一个对象元素,从而在它的内部使用ResourceDictionary.MergedDictionary
属性元素。除了 MergedDictionaries 属性元素,现有的ResourceDictionary 还可有其他键控资源。MergedDictionaries XAML 属性元素的内容包括一个或多个声明为 XAML 对象元素的 ResourceDictionary 项。表示合并字典的 ResourceDictionary 元素不能使用其他键控资源作为内容。相反,这些 ResourceDictionary 元素必须仅声明一个特性:Source。Source 值是引用资源字典的外部位置的方式。
例如,以下 XAML 定义了一个包含键控资源的 ResourceDictionary,以及一个引用了两个不同资源字典 XAML 文件的MergedDictionaries 集合。
<Application.Resources>
<ResourceDictionary>
<!--other resources can be here-->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="rd1.xaml" />
<ResourceDictionary Source="rd2.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
可以在 MergedDictionaries 中指定多个 ResourceDictionary。 在资源查找序列中,仅在检查声明ResourceDictionary 的所有键控资源后,才会检查 MergedDictionaries 字典。此后,搜索该级别时会深入到合并后的字典,且对 MergedDictionaries 中的每一项进行检查。如果存在多个合并的字典,会按在 MergedDictionaries 属性中声明这些字典的顺序的相反顺序来检查它们。在上一示例中,如果 "rd2.xaml" 和 "rd1.xaml" 均声明同一个键,则会首先使用来自 "rd2.xaml" 的键,因为它排在 MergedDictionaries 的末尾。
在任一 ResourceDictionary 范围内,均会检查字典中键的唯一性。但是,这一范围不会扩展到不同MergedDictionaries 文件中的不同项。
可以结合使用查找序列和跨合并字典范围不强制使用唯一键来创建 ResourceDictionary 资源的回退值序列。例如,你可能会使用与应用的状态数据和用户首选项数据同步的资源词典,为序列中最后合并的资源字典中的特殊笔刷颜色保存用户首选项。但是,如果尚不存在任何用户首选项,则可为初始 MergedDictionaries 文件中的 ResourceDictionary 资源定义相同的键字符串,并可将其用作回退值。 请记住,始终会在检查合并字典之前检查你在主要资源字典中提供的任何值,所以如果希望使用回退技术,请勿在主要资源字典中定义该资源。
主题字典
主题字典是一种特殊类型的合并字典,用于保存各种资源,具体资源取决于用户当前在其电脑上使用的主题。例如,“浅色”主题可能使用白色画笔,而默认主题可能使用黑色画笔。画笔会更改其所溶入的资源,但使用该画笔作为资源的控件的组成则可能保持不变。若要在个人模板或样式中重现主题切换行为而不将 MergedDictionaries 用作属性以将项目合并到主词典中,则应使 ThemeDictionaries 属性。与 MergedDictionaries 一样,请使用属性元素语法设置此属性,并且属性的值是一个或多个 ResourceDictionary 对象元素。
ThemeDictionaries 内的每个 ResourceDictionary 元素必须具有一个 x:Key 值。该值是一个字符串,它指定相关主题的名称,—例如,"Default"、"Light" 或 "HighContrast"。
包含的 ResourceDictionary 元素可使用两种可能的模型之一:
- ResourceDictionary 只有一个特性 Source,没有其他内容。Source 引用一个独立的 XAML 文件,该文件仅包含一个 ResourceDictionary 根。此字典然后定义特定于主题的键控项,该主题由指定 Source 的 ResourceDictionary 元素上的 x:Key 值命名。Source 值通常引用项目结构和应用包中的一个 XAML 文件。
- ResourceDictionary 包含内容,这些内容是特定于主题的键控项,该主题由父 ResourceDictionary 元素上的x:Key 值命名。
与合并的字典类似,在同一 ThemeDictionaries 集合中的一组主题字典中多次定义同一个键是合法的,只要该键在每个ResourceDictionary 单元中是唯一的。事实上,这是一种特意的设计:每个主题字典应该有一组相同的键。否则,任何缺少某个键的主题都可能在加载该主题时导致 UI 问题。与合并的字典不同的是,每个主题的定义的顺序无关紧要。对于主题字典,每当使用 ThemeResource 标记扩展进行引用并且系统检测到主题更改时,要用于资源查找的活动字典都会动态更改。系统查找行为以将活动主题映射到特定主题字典的 x:Key 为基础而执行。
检查主题字典在默认 XAML 设计资源中的构建方式十分有用,这些资源与 Windows 运行时默认用作其控件的模板相对应。在 IDE 中使用文本编辑器或类似编辑器以打开 \(Program Files)\Windows Kits\<version>\Include\winrt\xaml\design 中的 XAML 文件。请注意主题字典首先在 generic.xaml 中的定义方式,以及每个主题字典定义相同键的方式。然后每个这样的键由构成各种键控元素的元素所引用,这些键控元素位于主题字典外部并且稍后在 XAML 中定义。还存在用于设计的单独 themeresources.xaml 文件,该文件仅包含主题资源和额外模板,不包含默认控件模板。这些主题区域是你将在 generic.xaml 中看到的内容副本。
当你使用 XAML 设计工具以编辑模板和样式的副本时,该工具会提取 XAML 设计资源词典中的片段并将其作为应用和项目其中一部分的 XAML 字典元素的本地副本。
有关可用于使用 XAML 的 Windows 应用商店应用的特定于主题和系统资源的详细信息和列表,请参阅 XAML 主题资源引用。
Windows 8 行为
Windows 8 不支持 ThemeResource 标记扩展,该扩展自 Windows 8.1 开始提供支持。此外,Windows 8 也不支持动态切换 Windows 运行时应用的主题相关资源。必须重新启动应用,才能应用针对 XAML 模板和样式的主题更改。这种用户体验并不理想,因此强烈建议重新编译和定位 Windows 8.1,使其能通过 ThemeResource 使用样式,并能在用户执行相应操作时动态切换主题。对于为 Windows 8 编译的应用,如果其在 Windows 8.1 上运行,将继续使用 Windows 8 行为。
ResourceDictionary 中的前向引用
一个特定资源字典中的 XAML 资源引用必须引用定义了键的资源,并且从字典顺序来讲,该资源必须出现在资源引用之前。XAML 资源引用无法解析前向引用。出于此原因,如果你从另一个资源内使用 XAML 资源引用,则必须设计资源字典结构,以便使其他资源使用的资源在资源字典中首先定义。
在应用级别定义的资源不能引用直接资源。这相当于尝试前向引用,因为应用资源实际上最先被处理(在应用首次启动和加载任意导航页内容之前)。但是,任何直接资源都可引用应用资源,这可能是避免前向引用情形的一种有用技术。
UserControl 使用范围
对于资源查找行为,UserControl 元素有一个特殊情况,因为它有一个定义范围和使用范围的固有概念。从其定义范围内进行 XAML 资源引用的 UserControl 必须能够支持在其自己的定义范围查找序列中查找该资源—,也就是说,它不能访问应用资源。在 UserControl 使用范围中,将资源引用视为在朝向其使用页面根方向的查询序列内(就像从加载的对象树中的一个对象执行的任何其他资源引用一样),并且可访问应用资源。
ResourceDictionary 和 XamlReader.Load
你可以将 ResourceDictionary 用作根或用作 XamlReader.Load 方法的 XAML 输入的一部分。你还可以在该 XAML 中包含 XAML 资源引用(如果所有这类引用在提交加载的 XAML 中都是完全自包含的)。XamlReader.Load 在不了解任何其他 ResourceDictionary 对象(甚至不了解 Application.Resources)的上下文中分析 XAML。 此外,请不要从 XAML 内部使用提交到 XamlReader.Load 的 {ThemeResource}
。
通过代码使用 ResourceDictionary
大部分情况下,ResourceDictionary 均在 XAML 中专门处理。你要在 UI 定义文件中将内部的 ResourceDictionary容器和资源声明为 XAML 文件或 XAML 节点集。然后使用 XAML 资源引用从 XAML 的其他部分请求这些资源。不过,在某些特定情况下,你的应用可能需要使用在应用运行时执行的代码来调整 ResourceDictionary 的内容,或者至少需要查询 ResourceDictionary 的内容以查看是否已定义某资源。这些代码调用在一个 ResourceDictionary 实例上执行,所以必须首先检索一个 —,可通过获得 FrameworkElement.Resources 来检索对象树中某处的一个直接ResourceDictionary,或者检索 Application.Current.Resources
。
在 C# 或 Microsoft Visual Basic 代码中,你可以使用索引器 (Item) 引用特定 ResourceDictionary 中的资源。ResourceDictionary 是一个字符串键控字典,因此,索引器使用字符串键,而不使用整数索引。在 Visual C++ 组件扩展 (C++/CX) 代码中,请使用 Lookup。
当使用代码检查或更改 ResourceDictionary 时,API 的行为(如 Lookup 或 Item)不会从直接资源遍历到应用资源,这是仅在加载 XAML 页面时发生的 XAML 分析程序行为。在运行时,键作用域将自包含于此时所使用的ResourceDictionary 实例。但是,该作用域不会扩展到 MergedDictionaries 中。
另外,如果你请求的键不在 ResourceDictionary 中,可能不会出现错误;但返回值可能简单地提供为 null。但是,如果你尝试将返回的 null 用作值,仍然可能会出现错误。错误可能来自于属性的设置器,而不是你的ResourceDictionary 调用。避免错误的唯一方法是属性接受 null 作为有效值。请注意此行为与 XAML 解析期间的 XAML 查找行为有何区别;如果在解析期间无法解析从 XAML 提供的键,会导致 XAML 解析错误,甚至在属性可以接受null 时也是如此。
合并的资源字典包含在主要资源字典的索引范围内,该字典在运行时引用合并字典。换句话说,可以使用主要字典的Item 或 Lookup 查找在合并字典中实际定义的任何对象。在这种情况下,该查找行为类似于分析期间的 XAML 查找行为:如果合并字典中存在多个具有相同键的对象,将返回最后添加的字典中的对象。
你可以通过调用 Add(C# 或 Visual Basic)或 Insert (C++/CX) 向现有的 ResourceDictionary 添加项。你可以添加直接资源或应用资源。这些 API 调用中的每一个都需要一个键,这满足 ResourceDictionary 中的每个项都有一个键的要求。然而,你在运行时添加到 ResourceDictionary 的项与 XAML 资源引用无关。在加载应用期间首次分析 XAML 时,将执行必要的 XAML 资源引用查找。此时,在运行时添加到集合的资源不可用,而更改 ResourceDictionary 并不会使已从中检索到的资源失效,即使更改该资源的值也是如此。
你还可以在运行时从某个 ResourceDictionary 删除项,复制部分或所有项,或执行其他操作。ResourceDictionary的成员列表指出了哪些 API 可用。请注意,由于 ResourceDictionary 有一个投影的 API 可支持其基本集合接口,因此你的 API 选项会有所不同,具体取决于你使用的是 C# 或 Visual Basic,还是 C++/CX。
ResourceDictionary 和本地化
XAML ResourceDictionary 最初可能包含要本地化的字符串。如果是这样,将这些字符串存储为项目资源,而不存储在 ResourceDictionary 中。将字符串放在 XAML 外部,并为拥有元素提供一个 x:Uid 值。然后在资源文件中定义一个资源。以 XUIDValue.PropertyName 的形式提供资源名称,并提供应该本地化的字符串的资源值。有关详细信息,请参阅快速入门:翻译 UI 资源。
Windows 8.1 资源加载优化
从 Windows 8.1 开始,引入了由应用模型和 Windows 运行时 XAML 分析程序启用的资源加载优化机制。在 Windows 8 启动过程中,XAML 分析程序将从 app.xaml 加载资源并将其分别创建为对象。此时如果存在超大词典则会影响其加载效率。此外,这些资源包括为三个主题定义的项目,但真正需要的仅有当前主题。从 Windows 8.1 开始,XAML 分析程序只在 XAML 资源引用专门请求资源时创建它们。这些资源可能来自其他资源或来自每个页面加载时的页面级 XAML。优化的 XAML 分析程序行为会将启动时读取应用级词典的用时降至最低,同时使得应用的首个页面在多数情况下加速载入。对于非活动主题所需要的资源,只有在用户激活该主题时才会加载。运行应用的同时切换主题不是用户经常执行的操作。但是,如果发生该情况,会根据最新的活动主题,对使用 ThemeResource 标记扩展执行请求的所有资源进行重新计算。
Windows 8 行为
Windows 8 不具备上述优化功能。由于这一原因,当你针对 Windows 8.1 重新定位应用时可能会发现计时上的差别。重新定位后的应用应该具有更快的加载速度,但是这一改进同样离不开重新定位过程中的其他应用代码更改的作用。对于Application 对象、转换器或其他自定义类等对象,可能会因为优化了资源加载而发生计时方面的更改,这其中包括分析程序调用构造函数的时间。对于为 Windows 8 编译的应用,如果其在 Windows 8.1 上运行,将继续使用 Windows 8 行为。
自定义资源查找
对于高级方案,你可以实现其行为不同于本主题中描述的 XAML 资源引用查找行为的类。要达到此目的,你可实现类CustomXamlResourceLoader,然后可以通过使用 CustomResource 标记扩展进行资源引用(而不是使用StaticResource 或 ThemeResource)来实现该行为。大部分应用的方案将不会需要此操作。有关详细信息,请参阅CustomXamlResourceLoader。