三个回调对应依赖属性的验证过程,改变过程和强制转换过程。

class Dobj : DependencyObject
{
//依赖属性包装
public int MyProperty
{
get { return (int)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
} //注册依赖属性
//注意依赖属性默认值是:71
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(int), typeof(Dobj), new PropertyMetadata(, PropertyChanged, CoerceValue), ValidateValue); //属性改变
static void PropertyChanged(DependencyObject dobj, DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine(String.Format("PropertyChanged - 属性:{0} 新值:{1} 旧值:{2}", e.Property.Name, e.NewValue, e.OldValue));
} //强制转换
static object CoerceValue(DependencyObject dobj, object newValue)
{
Debug.WriteLine(String.Format("CoerceValue - {0}", newValue));
return newValue;
} //验证
static bool ValidateValue(object obj)
{
Debug.WriteLine(String.Format("ValidateValue - {0}", obj));
return true;
}
}

当仅仅定义一个新对象时:

var dobj = new Dobj();

调试下输出:

ValidateValue -
ValidateValue -

验证过程被执行了两次,我不知道为什么这样。

接着修改这个对象的属性。

var dobj = new Dobj();
dobj.MyProperty = ;

输出:

ValidateValue -
ValidateValue -
ValidateValue -
CoerceValue -
PropertyChanged - 属性:MyProperty 新值: 旧值:

默认值被验证了两遍,接着验证新值,强制转换,最后属性改变回调。

接下来修改一下验证回调,把返回值改为false。

//验证
static bool ValidateValue(object obj)
{
Debug.WriteLine(String.Format("ValidateValue - {0}", obj));
if ((int)obj == )
return false;
return true;
}

赋值语句(SetValue方法)会抛出ArgumentException异常,消息:’999′ is not a valid value for property ‘MyProperty’.(999并不是MyProperty属性的合法值)。

下面要做到内容是创建一个当前依赖对象的继承类,并改写父类依赖属性的元数据。

代码:

//继承原来的依赖对象
class SuperDobj : Dobj
{
static SuperDobj()
{
//改写父类依赖属性的元数据,默认值改成81
Dobj.MyPropertyProperty.OverrideMetadata(typeof(SuperDobj), new PropertyMetadata(, PropertyChanged, CoerceValue));
} //属性改变
static void PropertyChanged(DependencyObject dobj, DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine(String.Format("SuperDobj.PropertyChanged - 属性:{0} 新值:{1} 旧值:{2}", e.Property.Name, e.NewValue, e.OldValue));
} //强制转换
static object CoerceValue(DependencyObject dobj, object newValue)
{
Debug.WriteLine(String.Format("SuperDobj.CoerceValue - {0}", newValue));
if ((int)newValue == )
throw new Exception("test");
return newValue;
}
}

还是像刚才,先定义一个对象:

var superdobj = new SuperDobj();

输出:

ValidateValue -
ValidateValue -
ValidateValue –

父类和子类的验证都要执行一遍。

接着设置子类的依赖属性:

var superdobj = new SuperDobj();
superdobj.MyProperty = ;

输出:

ValidateValue -
ValidateValue -
ValidateValue -
ValidateValue -
SuperDobj.CoerceValue -
PropertyChanged - 属性:MyProperty 新值: 旧值:
SuperDobj.PropertyChanged - 属性:MyProperty 新值: 旧值:

这个结果很有意思。

看来子类和父类的验证和属性改变回调都会依次被调用,但是强制转换只调用子类的。

事实上属性元数据此时会调用PropertyMetadata.Merge方法来合并多个属性元数据。可以参考MSDN:http://msdn.microsoft.com/zh-cn/library/system.windows.propertymetadata.merge.aspx

原文地址:https://www.mgenware.com/blog/?p=188

【转】【WPF】关于依赖属性的ValidateValueCallback,PropertyChangedCallback和CoerceValueCallback的执行顺序的更多相关文章

  1. WPF的依赖属性

    Windows Presentation Foundation (WPF) 提供了一组服务,这些服务可用于扩展公共语言运行时 (CLR)属性的功能,这些服务通常统称为 WPF 属性系统.由 WPF 属 ...

  2. WPF的依赖属性和附加属性(用法解释较全)

    转:https://www.cnblogs.com/zhili/p/WPFDependencyProperty.html 一.引言 感觉最近都颓废了,好久没有学习写博文了,出于负罪感,今天强烈逼迫自己 ...

  3. wpf 的依赖属性只能在loaded 事件之后才能取到

    wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的  InitializeComponent(); 之后取不到 wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的  ...

  4. WPF 中依赖属性的继承(Inherits)

    WPF中依赖属性的值是是可以设置为可继承(Inherits)的,这种模式下,父节点的依赖属性会将其值传递给子节点.例如,数据绑定中经常使用的DataContextProperty: var host ...

  5. WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性

    原文:WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性 如果你要自定义一个图片按钮控件,那么如何在主窗体绑定这个控件上图片的Source呢? ...

  6. [转]WPF的依赖属性是怎么节约内存的

    WPF升级了CLR的属性系统,加入了依赖属性和附加属性.依赖属性的使用有很多好处,其中有两点是我认为最为亮眼的: 1)节省内存的开销; 2)属性值可以通过Binding依赖于其它对象上,这就使得我的数 ...

  7. WPF利用依赖属性和命令编写自定义控件

    以实例讲解(大部分讲解在代码中) 1,新建一个WPF项目,添加一个用户控件之后在用户控件里面添加几个控件用作测试, <UserControl x:Class="SelfControlD ...

  8. WPF: 只读依赖属性的介绍与实践

    在设计与开发 WPF 自定义控件时,我们常常为会控件添加一些依赖属性以便于绑定或动画等.事实上,除了能够添加正常的依赖属性外,我们还可以为控件添加只读依赖属性(以下统称"只读属性" ...

  9. WPF 自定义依赖属性

      原博客地址:http://www.cnblogs.com/DebugLZQ/archive/2012/11/30/2796021.html    DependencyObject和Dependen ...

随机推荐

  1. hot-warm-architecture-in-elasticsearch-5-x

    https://www.elastic.co/blog/hot-warm-architecture-in-elasticsearch-5-x https://www.elastic.co/blog/e ...

  2. 实例分析JVM安全体系:双亲委派、命名空间、保护域、策略

    在了解双亲委派模型之前,先了解一下类加载器的概念: 类加载器的作用就是将真实的class文件根据位置将该Java类的字节码装入内存,并生成对应的Class对象.用户可以通过继承ClassLoader和 ...

  3. (原创)c++11中的日期和时间库

    c++11提供了日期时间相关的库chrono,通过chrono相关的库我们可以很方便的处理日期和时间.c++11还提供了字符串的宽窄转换功能,也提供了字符串和数字的相互转换的库.有了这些库提供的便利的 ...

  4. [iOS]终极横竖屏切换解决方案

    [iOS]终极横竖屏切换解决方案 大家的项目都是只支持竖屏的吧?大多数朋友(这其中当然也包括博主),都没有做过横屏开发,这次项目刚好有这个需求,因此把横竖屏相关的心得写成一遍文章供诸位参考. 01.综 ...

  5. 1. K-Means原理解析

    1. K-Means原理解析 2. K-Means的优化 3. sklearn的K-Means的使用 4. K-Means和K-Means++实现 1. 前言 我们在一开始的时候应该就说过,机器学习按 ...

  6. js实现完美身份证号有效性验证(转)

    转载自:http://www.cnblogs.com/lzrabbit/archive/2011/10/23/2221643.html 最近需要对身份证合法性进行验证,实名验证是不指望了,不过原来的验 ...

  7. Memcaced多站点登录图解

  8. Eclipse 常用插件安装(最新更新:2016-12-06)

    . . . . . Eclipse 用得久了,不停地填充着各种好用的插件.由于我的版本较低,不支持插件导出功能(3.7以上支持),所以把各种体验比较好的插件记录在这里,以便将来全量升级Eclipse时 ...

  9. StreamingContext.getOrCreate

    /** */ object AppRealTime { def main(args: Array[String]): Unit = { ) { println("please input a ...

  10. 【转载】TCP协议要点和难点全解

    说明: 1).本文以TCP的发展历程解析容易引起混淆,误会的方方面面 2).本文不会贴大量的源码,大多数是以文字形式描述,我相信文字看起来是要比代码更轻松的 3).针对对象:对TCP已经有了全面了解的 ...