附加属性

Download Sample下载示例

附加属性使对象能够为其自己的类未定义的属性分配值。 例如,子元素可以使用附加属性告知其父元素如何在用户界面中呈现。 借助 Grid 控件,可通过设置 Grid.RowGrid.Column 附加属性来指定子项的行和列。 Grid.RowGrid.Column 为附加属性,因为它们是在作为 Grid 子元素的元素上设置的,而不是在 Grid 自身上设置的。

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

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

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

创建附加属性

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

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

创建属性

创建用于其他类型的附加属性时,创建属性的类不必派生自 BindableObject。 但是,访问器的目标属性应当为或派生自 BindableObject

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

重要

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

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

public static readonly BindableProperty HasShadowProperty =
  BindableProperty.CreateAttached ("HasShadow", typeof(bool), typeof(ShadowEffect), false);

这会创建一个类型为 bool,名称为 HasShadowProperty 的附加属性。 该属性属于 ShadowEffect 类,默认值为 false

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

创建访问器

需要将静态 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 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:EffectsDemo" ...>
  ...
</ContentPage>

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

<Label Text="Label Shadow Effect" local:ShadowEffect.HasShadow="true" />

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

var label = new Label { Text = "Label Shadow Effect" };
ShadowEffect.SetHasShadow (label, true);

通过样式使用附加属性

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

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

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

<Label Text="Label Shadow Effect" Style="{StaticResource ShadowEffectStyle}" />

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

高级方案

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