定义和使用资源

已完成

资源就像编程语言中的符号常量。 在一个位置定义资源后,即可在需要它的任意位置引用它。 由于使用的是描述性名称而非“magic”值,代码更易于阅读。 如果需要更改值,只需更新定义即可。

本模块介绍如何使用资源来消除 XAML 中的硬编码值。

什么是资源?

资源是可以在 UI 中共享的任何对象。 最常见的示例是字体、颜色和字号。 但是,也可以将复杂对象(例如 Style 和 OnPlatform 实例)作为资源进行存储。

可以在 XAML 或代码中定义资源。 然后在 XAML 或代码中应用它。 通常情况下,完全在 XAML 中使用,但我们稍后会介绍一些代码有用的案例。

构想一个示例。 假设你要在页面上的不同控件中使用相同的 TextColor 值。 如果使用了硬编码值,则 XAML 将如下所示。 请注意文本颜色的值在两个控件中的重复方式。

<Label TextColor="Blue" FontSize="14">
<Button TextColor="Blue" FontSize="14">

可以将文本颜色定义为资源,而不是重复它。 该定义类似于以下 XAML:

<Color x:Key="PageControlTextColor">Blue</Color>

请注意,现在定义的元素包含一个用于指定资源名称的 x:Key 属性。 可以使用此键在 XAML 中查找资源。

在使用某个资源之前,必须将其存储在资源字典中。

什么是 ResourceDictionary?

ResourceDictionary 是为了与 UI 资源配合使用而自定义的 .NET MAUI 库类。 它是一个字典,因此它存储了键/值对。 键的类型仅限于字符串,而值可以是任何对象。

每个 .NET MAUI XAML 页面具有一个名为 Resources 的属性,该属性可以包含 ResourceDictionary 对象。 默认情况下,该属性为 null,因此需要先创建字典实例,然后才能使用它。 以下代码演示如何创建 ResourceDictionary 对象并将其分配给 ContentPage 的 Resources 属性:

<ContentPage.Resources>
    <ResourceDictionary>
        ...
    </ResourceDictionary>
</ContentPage.Resources>

.NET MAUI XAML 提供内置的便利语法,每当你开始使用 Resources 属性时,该语法都会自动创建字典实例。 前面的示例可以简化为以下代码:

<ContentPage.Resources>
    ...
</ContentPage.Resources>

应用中的每个页面可以有自身的字典。 使用这些特定于页面的字典来存储仅在该页面上使用的资源。

注意

页面上的每个控件也可以有自身的资源字典。 例如,可将资源目录添加到 Label 控件,如下所示:

<Label Text="Hello, World!"
        ...
        <Label.Resources>
           ...
        </Label.Resources>
</Label>

除了可以容纳子元素的布局和视图之外,在控件级别执行此操作并不常见。

创建资源

若要创建某个资源,请在页面的 Resources 属性中声明该资源。 以下示例创建前面描述的文本颜色资源

<ContentPage.Resources>
    <Color x:Key="PageControlTextColor">Blue</Color>
</ContentPage.Resources>

为资源选择键时,请选择一个反映资源用途而不是资源值的名称。 例如,若要将标签的背景设置为红色,请不要使用 RedColor 作为键,而是使用 BackgroundColor。

使用 StaticResource 应用资源

StaticResource 是用于在资源字典中查找资源的标记扩展。 提供资源的键后,标记扩展会返回相应的值。 以下 XAML 标记显示了一个创建和使用名为 PageControlTextColor 的 Color 资源的示例。 示例中标签控件的 XAML 标记使用 StaticResource 标记扩展来检索值。

<ContentPage.Resources>
    <Color x:Key="PageControlTextColor">Blue</Color>
</ContentPage.Resources>

...

<Label TextColor="{StaticResource PageControlTextColor}" ... />

该扩展名为 StaticResource,因为该扩展只评估一次。 创建目标对象时进行字典查找。 如果字典中的资源值更改,则不会更新目标属性。

警告

如果找不到键,StaticResource 将引发运行时异常。

XAML 内部类型

本单元开头提供的原始示例设置 TextColor 属性和 FontSize 属性:

<Label TextColor="Blue" FontSize="14">
<Button TextColor="Blue" FontSize="14">

FontSize 的类型为 Double。 若要为此值创建资源,请使用 XAML 规范中定义的 XAML 内部类型之一。 XAML 规范定义了许多 C# 简单类型的类型名称。 以下代码演示了每个内部类型的示例资源。

<ContentPage.Resources>
    <x:String x:Key="...">Hello</x:String>
    <x:Char x:Key="...">X</x:Char>
    <x:Single x:Key="...">31.4</x:Single>
    <x:Double x:Key="...">27.1</x:Double>
    <x:Byte x:Key="...">8</x:Byte>
    <x:Int16 x:Key="...">16</x:Int16>
    <x:Int32 x:Key="...">32</x:Int32>
    <x:Int64 x:Key="...">64</x:Int64>
    <x:Decimal x:Key="...">12345</x:Decimal>
    <x:TimeSpan x:Key="...">1.23:5959</x:TimeSpan>
    <x:Boolean x:Key="...">True</x:Boolean>
</ContentPage.Resources>

为资源设置特定于平台的值

在各个平台之间,通常需要简单调整应用的 UI。 定义特定于平台的值的标准方法是在定义资源时使用 OnPlatform 对象。 例如,以下代码演示如何在 iOS、Android、macOS (Mac Catalyst) 和 Windows (WinUI) 上创建引用不同文本颜色的资源。

<ContentPage.Resources>
    <OnPlatform x:Key="textColor" x:TypeArguments="Color">
        <On Platform="iOS" Value="Silver" />
        <On Platform="Android" Value="Green" />
        <On Platform="WinUI" Value="Yellow" />
        <On Platform="MacCatalyst" Value="Pink" />
    </OnPlatform> 
</ContentPage.Resources>
...

<Label TextColor="{StaticResource textColor}" ... />

知识检查

1.

StaticResource 引用的值将分配给变量。 值更改后会发生什么?