一、概述
在定义任何类型的属性时,都需要面对错误设置属性的可能性。对于传统的.NET属性,可尝试在属性设置器中捕获这类问题。但对于依赖属性而言,这种方法不合适,因为可能通过WPF属性系统可使用SetValue()方法直接设置属性。
作为替代,WPF提供了两种方法来阻止非法值:
(1)ValidateValueCallback:该回调函数可接受或拒绝新值。通常用于捕获违反属性约束的明显错误。可作为DependencyProperty.Register()方法或DependencyProperty.RegisterAttached()方法的一个参数提供该回调函数。
(2)CoerceValueCallback:该回调函数可将新值修改为更能被接受的值。该回调函数通常用于为同一对象设置的依赖属性值相互冲突的问题。这些值本身可能是合法的,但同时应用它们是不相容的。为了使用这个回调函数,当创建FrameworkPropertyMetadata对象时,作为构造函数的一个参数提供该回调函数。然后这个对象被传递到DependencyProperty.Register()方法。
二、依赖属性赋值验证过程
(1)CoerceValueCallback
(2)ValidateValueCallback,该方法返回true表示合法值,false表示非法值。
(3)PropertyChangedCallback,如果前两个阶段都获得成功,就会触发该方法,此时,如果希望为其它类提供通知,可以引发更改事件。
三、验证回调
例如,对MarginProperty的属性赋值时的验证回调。
static FrameworkElement()
{
FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(new Thickness(), FrameworkPropertyMetadataOptions.AffectsMeasure);
MarginProperty = DependencyProperty.Register("Margin", typeof(Thickness), typeof(FrameworkElement), metadata, new ValidateValueCallback(FrameworkElement.IsMarginValid));
……
}
回调函数:private static bool IsMarginValid(object value)
{
Thickness thickness1 = (Thickness)value;
return thickness1.IsValid(true,false,true,false);
}
此时若给Margin赋值为负数,则IsMarginValid方法将返回false。
四、强制回调
例如,当对控件宽度尺寸的Maximum属性进行设置时,必须使用强制以确保不能小于Minimum属性的值。
具体实例需要进一步学习,暂时先留个坑,详见书P91。