依赖属性
与.Net属性对比:
更高效
支持附加功能
更改通知
属性值继承
创建依赖属性
/// <summary>
/// 只能为依赖对象添加依赖属性
/// </summary>
public class DependencyClass : DependencyObject
{
/// <summary>
/// 定义依赖属性
/// 约定俗成命名规则:属性名+Property
/// </summary>
public static readonly DependencyProperty NumberProperty =
DependencyProperty.Register(//注册依赖属性
"Number", //属性名
typeof(int), //属性类型
typeof(DependencyClass), //拥有该属性的类型
new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender),//附加属性对象*
new ValidateValueCallback(DependencyClass.IsZero));//值验证回调*
/// <summary>
/// 创建属性封装器,用于像设置普通属性一样设置依赖属性
/// </summary>
public int Number
{
get => (int)GetValue(NumberProperty);
set => SetValue(NumberProperty, value);
}
/// <summary>
/// 回调方法
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static bool IsZero(object value)
{
return (int) value == 0;
}
}
*为可选项
共享依赖属性
不同的类可使用DependencyProperty.AddOwner方法共享同一依赖项属性
重用依赖项属性可能导致预期外的结果
- Eg : 使用样式修改TextBlock.FontFamily属性也会印象Control.FontFamily属性,因为共用一个依赖项属性
TextBlock.FontFamilyProperty = TextElement.FontFamilyProperty.AddOwner(typeof(TextBlock));
附加依赖属性
附加依赖项属性使用DependencyProperty.RegisterAttached方法应用到类(非定义依赖属性的类)
- Eg : Grid的Column和Row附加属性
附加属性需要定义两个静态方法来设置和获取属性值
使用属性包装器中的GetValue和SetValue方法
约定俗成的命名规则:GetPropertyName和SetPropertyName
public static readonly DependencyProperty ColumnProperty =
DependencyProperty.RegisterAttached(
"Column",
typeof(int),
typeof(Grid),
new FrameworkPropertyMetadata(
0,
new PropertyChangedCallback(OnCellAttachedPropertyChanged)),
new ValidateValueCallback(IsIntValueNotNegative));
public static void SetColumn(UIElement element, int value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(ColumnProperty, value);
}
public static int GetColumn(UIElement element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return ((int)element.GetValue(ColumnProperty));
}
元数据 FrameworkPropertyMetadata
- 标识依赖属性的特征
Name | Comment |
---|---|
AffectsArrange、AffectsMeasure、AffectsParentArrange和AffectsParentMeasure | 该值表示依赖属性是否会影响布局引擎操作期间的排列和测量过程中如何放置相邻的元素或父元素。 |
AffectsRender | 该值指示依赖属性是否会以某种方式影响元素绘制方式,要求重新绘制元素。 |
BindsTwoWayByDefault | 该值指示默认情况下属性是否双向绑定。 |
CoerceValueCallback | 该属性提供了一个用于在验证依赖项属性之前尝试“纠正”属性值的回调函数。 |
DefaultUpdateSourceTrigger | 该值表示 UpdateSourceTrigger 的默认值。 |
DefaultValue | 该值表示依赖属性的默认值。 |
Inherits | 该值指示依赖属性的值是否可继承。 |
IsAnimationProhibited | 该值指示是否应在应用了包含元数据实例的依赖项对象上禁用动画。True为禁用。 |
IsNotDataBindable | 该值指示依赖属性是否支持数据绑定。True为禁用。 |
Journal | 该值表示该属性是否包含应用程序可以或应该作为日记功能实现的一部分而存储的日记信息。 |
OverridesInheritanceBehavior | 该值指示属性值继承计算是否应跨越元素逻辑树中的某些内容边界。 |
PropertyChangedCallback | 该属性提供了一个用于在依赖项属性值改变后触发的回调函数。 |
SubPropertiesDoNotAffectRender | 该值指示依赖属性的子属性是否影响包含对象的重绘。 |
属性验证回调 ValueCallBack
类型
CoerceValueCallBack : 尝试验证并将属性值改为可接受的值
ValidateValueCallBack : 接受或者拒绝属性值
触发过程
激活 CoerceValueCallBack 函数尝试修改属性,或者返回DependencyProperty.UnsetValue表示拒绝修改
激活 ValidateValueCallBack 函数验证属性值是否合法
前面两个阶段均成功则触发PropertyChangedCallback函数通知属性值已修改