附加属性
附加属性使对象能够为其自己的类未定义的属性分配值。 例如,子元素可以使用附加属性告知其父元素如何在用户界面中呈现。 借助 Grid
控件,可通过设置 Grid.Row
和 Grid.Column
附加属性来指定子项的行和列。 Grid.Row
与 Grid.Column
为附加属性,因为它们是在作为 Grid
子元素的元素上设置的,而不是在 Grid
自身上设置的。
在以下方案中,应将可绑定属性作为附加属性实现:
- 当需要一种可用于类(定义类除外)的属性设置机制时。
- 当类表示需要与其他类轻松集成的服务时。
有关可绑定属性的详细信息,请参阅可绑定属性。
创建附加属性
创建附加属性的过程如下所示:
- 使用其中一种
CreateAttached
方法重载创建BindableProperty
实例。 - 提供
static
Get
PropertyName 和Set
PropertyName 方法作为附加属性的访问器。
创建属性
创建用于其他类型的附加属性时,创建属性的类不必派生自 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
。
有关创建可绑定属性的详细信息,包括可在创建过程中指定的参数,请参阅创建可绑定属性。
创建访问器
需要将静态 Get
PropertyName 和 Set
PropertyName 方法作为附加属性的访问器,否则属性系统将无法使用附加属性。 Get
PropertyName 访问器应当符合以下签名:
public static valueType GetPropertyName(BindableObject target)
Get
PropertyName 访问器应返回附加属性的相应 BindableProperty
字段中包含的值。 这可以通过调用 GetValue
方法实现,传入要获取值的可绑定属性标识符,然后将生成的值强制转换为所需类型。
Set
PropertyName 访问器应符合以下签名:
public static void SetPropertyName(BindableObject target, valueType value)
Set
PropertyName 访问器应设置附加属性的相应 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}" />
有关样式的详细信息,请参阅 样式。
高级方案
创建附加属性时,可以设置许多可选参数来启用高级附加属性方案。 这包括检测属性更改、验证属性值和强制属性值。 有关详细信息,请参阅高级方案。