【WPF学习】第十二章 属性验证
2021-01-13 13:31
标签:静态方法 typeof pyc 依赖 pen 内容 适应 更改 logs
在定义任何类型的属性时,都需要面对错误设置属性的可能性。对于传统的.NET属性,可尝试在属性设置器中捕获这类问题。但对于依赖项属性而言,这种方法不合适,因为可能通过WPF属性系统使用SetValue()方法直接设置属性。 作为代替,WPF提供了两种方法来阻止非法值: 下面是当应用程序试图设置依赖项属性时,所有这些内容的作用过程: (1)首先,CoerceValueCallback方法有机会修改提供的值(通常,使提供的值和其他属性相容),或者返回DependencyProperty.UnsetValue,这会完全拒绝修改。 (2)接下来激活ValidateValueCallback方法。该方法返回true以接受一个值作为合法值,或者返回false拒绝值。与CoerceValueCallback方法不同,ValidateValueCallback方法不能访问设置属性的实际对象,这意味着你不能检查其他属性值。 (3)最后,如果前两个阶段都获得成功,就会触发PropertyChangedCallback方法。此时,如果希望为其他类提供通知,可以引发更改事件。 一、验证回调 正如前面所看到的,DependencyProperty.Register()方法接受可选的验证回调函数: 可使用这个回调函数验证,验证通常应被添加到属性过程的设置部分。提供的回调函数必须指向一个接受对象参数并返回Boolean值得方法。返回true以接受对象是合法的,返回false拒绝对象。 对FrameworkElement.Margin属性的验证十分枯燥乏味,因为它依赖于内部的Thickness.IsValid()方法。该方法确保当前使用的Thickness对象(表示边距)是合法的。例如,可能构造了一个完全可以接受的Thickness对象(却不适于设置边距)。一个例子是Thickness对象使用了负值。如果提供的Thickness对象对于边距时是不合法的。IsMarginValid方法将返回false: 对于验证回调函数有一个限制:它们必须是静态方法而且无权访问正在被验证的对象。所有能够获得的信息只有刚刚应用的数值。尽管这样更便于重用属性,但可能无法创建考虑其他属性的验证例程。典型的例子是具有Maximum和Minimum属性的元素。显然,为Maximum属性设置的值不能小于为Minimum属性设置的值。但是,不能使用验证回调函数来实施这一逻辑,因为一次之恩你访问一个属性。 二、强制回调 通过FrameworkPropertyMetadata对象使用CoerceValueCallback回调函数。下面是示例: 可以通过CoerceValueCallback回调函数处理相互关联的属性。例如,ScrollBar控件提供了Maximum、Minimum和Value属性,这些属性都继承自RangeBase类。保持对这些属性进行调整的一种方法是使用属性强制。 例如,当设置Maximum属性时,必须使用强制以确保不能小于Minimum属性的值: 换句话说,如果应用于Maximum属性的值小于Minimum属性的值,就用Minimum属性的值设置Maximum属性。注意,CoerceValueCallback传递两个参数——准备使用的数值和该数值将要应用到得对象。 当设置Value属性时,会发生类似的强制过程。对Value属性进行强制,确保不会超出由Minimum和Maximum属性定义的范围,使用下面的代码: Minimum属性根本不使用值强制。相反,一旦值发生变化,就触发PropertyChangedCallback,然后通过手动触发Maximum和Value属性的强制过程,使它们适应Minimum属性值得变化: 类似地,一旦设置或强制Maximum属性的值,那么也会手动强制Value属性以适应Maximum属性值得变化: 如果设置的值相互冲突,最终结果是Minimum属性具有优先权,其次是Maximum属性(并且可能会被Minimum属性强制),最后是Value属性(并且可能会被Maximum和Minimum属性强制)。 【WPF学习】第十二章 属性验证 标签:静态方法 typeof pyc 依赖 pen 内容 适应 更改 logs 原文地址:https://www.cnblogs.com/lonelyxmas/p/12285949.html
static FrameworkElement(){
FrameworkPropertyMetadata metadata=new FrameworkPropertyMetadata(new Thickness(),FrameworkPropertyMetadataOptions.AffectsMeasure);
MarginProperty=DependencyProperty.Register("Margin",typeof(Thickness),typeof(FrameworkElement),metadata,new ValidateValueCallback(FrameworkElement.IsMarginValid));
....
}
public static bool IsMarginValid(object value)
{
Thickness thickness1=(Thickness)value;
return thickness1.IsValid(true,false,true,false);
}
FrameworkPropertyMetadata metadata=new FrameworkPropertyMetadata(new Thickness(),FrameworkPropertyMetadataOptions.AffectsMeasure);
metadata.CoerceValueCallback=new CoerceValueCallback(CoerceMaximum);
DependencyProperty.Register("Maxium",typeof(double),typeof(RangeBase),metadata);
private static object CoerceMaximum(DependencyObject d,object value)
{
RangeBase base1=(RangeBase)d;
if((double)value)base1.Minimum)
{
return base1.Minimum;
}
return value;
}
internal static object ConstrainToRange(DependencyObject d,object value)
{
double newValue=(double)value;
RangeBase base1=(RangeBase)d;
double minimum=base1.Minimum;
if(newValueminimum)
{
return minimum;
}
double maximum=bas1.Maximum;
if(newValue>maximum)
{
return maximum;
}
return newValue;
}
private static void OnMinimumChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
RangeBase base1=(RangeBase)d;
...
base1.CoerceValue(RangeBase.MaximumProperty);
base1.CoerceValue(RangeBase.ValueProperty);
}
private static void OnMaximumChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
RangeBase base1=(RangeBase)d;
...
base1.CoerceValue(RangeBase.ValueProperty);
base1.OnMaximumChanged((double)e.OldValue,(double)e.NewValue);
}
下一篇:多线程基础