摘要:第 10 章. XAML 标记扩展

注意

本书于 2016 年春季出版,之后再未更新。 书中有许多内容仍然有价值,但有些内容已过时,有些主题不再完全正确或完整。

通常,XAML 分析器会根据基本 .NET 数据类型的标准转换或通过 TypeConverterAttribute 附加到属性或其类型的 TypeConverter 派生,将设置为属性值的任何字符串转换为属性的类型。

但是有时从其他源(例如,字典中的项、静态属性或字段的值或从某种类型的计算)设置属性会非常方便。

这是 XAML 标记扩展执行的操作。 尽管名称如此,但 XAML 标记扩展并不是 XML 的扩展。 XAML 始终是合法的 XML。

代码基础结构

XAML 标记扩展是实现 IMarkupExtension 接口的类。 这种类通常在其名称的末尾带有 Extension 一词,但通常在 XAML 中不带有该后缀。

XAML 的所有实现均支持以下 XAML 标记扩展:

XAML 的许多实现都支持这四个 XAML 标记扩展,包括 Xamarin.Forms:

Xamarin.Forms 中包含与 RelativeLayout 相关的附加 XAML 标记扩展:

访问静态成员

使用 x:Static 元素可将属性设置为公共静态属性、字段或枚举成员的值。 将 Member 属性设置为静态成员。 通常用大括号来指定 x:Static 和成员名称会更加容易。 不需要包含 Member 属性的名称,只需包含成员本身。 此常见语法如 SharedStatics 示例中所示。 静态字段本身在 AppConstants 类中定义。 这种技术允许你建立通过程序使用的常量。

使用其他 XML 命名空间声明,你可以引用 .NET Framework 中定义的公共静态属性、字段或枚举成员,如 SystemStatics 示例中所示。

资源字典

VisualElement 类将定义一个名为 Resources 的属性,可以将其设置为 ResourceDictionary 类型的对象。 在 XAML 中,可以将项目存储在此字典中,并使用 x:Key 属性对其进行标识。 存储在资源字典中的项将在对该项的所有引用之间共享。

StaticResource 适用于大多数情况

在大多数情况下,将使用 StaticResource 标记扩展来引用资源字典中的项,如 ResourceSharing 示例所示。 可以在大括号内使用 StaticResourceExtension 元素或 StaticResource

资源共享的三倍屏幕截图

请勿混淆 x:Static 标记扩展和 StaticResource 标记扩展。

字典树

当 XAML 分析器遇到 StaticResource 时,它将开始在可视化树中搜索匹配键,然后在应用程序的 App 类中查找 ResourceDictionary。 这样,位于可视化树中较深层的资源字典中的项可覆盖位于可视化树中较高层的资源字典。 ResourceTrees 示例对此进行了演示。

DynamicResource 适用于特殊情况

InitializeComponent 调用期间生成可视化树时,StaticResource 标记扩展会导致从字典中检索项。 StaticResource 的一种替代方法是 DynamicResource,这种方法可维护字典键的链接,并在键引用的项更改时更新目标。

DynamicVsStatic 示例说明了 StaticResourceDynamicResource 之间的区别。

DynamicResource 设置的属性必须由可绑定属性提供支持,如第 11 章,可绑定基础结构中所述。

较少使用的标记扩展

使用 x:Null 标记扩展将属性设置为 null

使用 x:Type 标记扩展将属性设置为 .NET Type 对象。

使用 x:Array 定义一个数组。 通过将 [Type] 属性设置为 x:Type 标记扩展来指定数组成员的类型。

自定义标记扩展

通过使用 ProvideValue 方法编写实现 IMarkupExtension 接口的类,可以创建自己的 XAML 标记扩展。

HslColorExtension 类满足以下要求。 它基于名为 HSLA 的属性值创建类型为 Color 的值。 此类是名为 Xamarin.FormsBook.Toolkit 的 Xamarin.Forms 库中的第一项,它在本书中构建,并在本书中使用。

CustomExtensionDemo 示例演示了如何引用此库并使用自定义标记扩展。