附加属性

.NET Multi-platform App UI (.NET MAUI) 附加属性使对象能够为自己的类未定义的属性分配值。 例如,子元素可以使用附加属性告知其父元素如何在用户界面中呈现。 Grid 布局允许通过设置 Grid.RowGrid.Column 附加属性指定子元素的行和列。 Grid.RowGrid.Column 为附加属性,因为它们是在作为 Grid 子元素的元素上设置的,而不是在 Grid 自身上设置的。

在以下方案中,应将可绑定属性作为附加属性实现:

  • 当需要一种可用于类(定义类除外)的属性设置机制时。
  • 当类表示需要与其他类轻松集成的服务时。

有关可绑定属性的详细信息,请参阅可绑定属性

创建附加属性

创建附加属性的过程如下所示:

  1. 使用其中一种 CreateAttached 方法重载创建 BindableProperty 实例。
  2. 提供 staticGetPropertyNameSetPropertyName 方法作为附加属性的访问器。

创建属性

创建用于其他类型的附加属性时,创建属性的类不必派生自 BindableObject。 但是,访问器的目标属性应当为或派生自 BindableObject。 有关目标属性的详细信息,请参阅基本绑定

可以通过声明 BindableProperty 类型的 public static readonly 属性创建附加属性。 可绑定属性应当设置为 BindableProperty.CreateAttached 方法重载之一的返回值。 声明应位于拥有类的正文内,但不属于任何成员定义。

重要

附加属性的命名约定是附加属性标识符必须与 CreateAttached 方法中指定的属性名称匹配,并将“属性”追加到其中。

下面的代码显示一个附加属性的示例:

public class MyControl
{
    public static readonly BindableProperty HasShadowProperty =
        BindableProperty.CreateAttached("HasShadow", typeof(bool), typeof(MyControl), false);
}

这会创建一个类型为 bool,名称为 HasShadowProperty 的附加属性。 该属性属于 MyControl 类,默认值为 false。 在本例中,所有权意味着将使用格式 Type.Property 的 XAML 访问该属性,例如 MyControl.HasShadow

有关创建可绑定属性的详细信息,包括可在创建过程中指定的参数,请参阅创建可绑定属性

创建访问器

需要将静态 GetPropertyNameSetPropertyName 方法作为附加属性的访问器,否则属性系统将无法使用附加属性。 GetPropertyName 访问器应当符合以下签名:

public static valueType GetPropertyName(BindableObject target)

GetPropertyName 访问器应返回附加属性的相应 BindableProperty 字段中包含的值。 这可以通过调用 GetValue 方法实现,传入要获取值的可绑定属性标识符,然后将生成的值强制转换为所需类型。

SetPropertyName 访问器应符合以下签名:

public static void SetPropertyName(BindableObject target, valueType value)

SetPropertyName 访问器应设置附加属性的相应 BindableProperty 字段的值。 可以通过调用 SetValue 方法、传入要设置值的可绑定属性标识符和要设置的值达成此目的。

对于这两个访问器,目标对象应当为或派生自 BindableObject。 有关目标对象的详细信息,请参阅基本绑定

下面的代码示例显示 HasShadow 附加属性的访问器:

public class MyControl
{
    public static bool GetHasShadow(BindableObject view)
    {
        return (bool)view.GetValue (HasShadowProperty);
    }

    public static void SetHasShadow(BindableObject view, bool value)
    {
        view.SetValue(HasShadowProperty, value);
    }  
}

使用附加属性

创建附加属性后,可以从 XAML 或代码使用它。 在 XAML 中,此操作可通过声明带有前缀的命名空间,并使用指示公共语言运行时 (CLR) 命名空间名称的命名空间声明以及程序集名称(可选)实现。 有关详细信息,请参阅 XAML 命名空间

以下示例展示包含附加属性的自定义类型的 XAML 命名空间,该命名空间在同一个程序集内定义为引用自定义类型的应用代码:

<ContentPage ... xmlns:local="clr-namespace:ShadowDemo" ...>
  ...
</ContentPage>

然后在特定控件上设置附加属性时使用命名空间声明,如以下 XAML 所示:

<Label Text="Label with shadow" local:MyControl.HasShadow="true" />

以下代码示例显示相应的 C# 代码:

Label label = new Label { Text = "Label with shadow" };
MyControl.SetHasShadow (label, true);

通过样式使用附加属性

还可以通过样式将附加属性添加到控件。 下面的 XAML 代码示例显示使用 HasShadow 附加属性的 Label 控件的显式样式:

<Style x:Key="ShadowStyle" TargetType="Label">
  <Style.Setters>
    <Setter Property="local:MyControl.HasShadow" Value="true" />
  </Style.Setters>
</Style>

Style 可通过使用 StaticResource 标记扩展将 Style 属性设置为 Style 实例来应用于 Label,如以下代码示例所示:

<Label Text="Label with shadow" Style="{StaticResource ShadowStyle}" />

有关样式的详细信息,请参阅 样式

高级方案

创建附加属性时,可以设置一些可选参数来启用高级附加属性方案。 这包括检测属性更改、验证属性值和强制属性值。 有关详细信息,请参阅高级方案