【转】【WPF】关于依赖属性的ValidateValueCallback,PropertyChangedCallback和CoerceValueCallback的执行顺序
三个回调对应依赖属性的验证过程,改变过程和强制转换过程。
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的执行顺序的更多相关文章
- WPF的依赖属性
Windows Presentation Foundation (WPF) 提供了一组服务,这些服务可用于扩展公共语言运行时 (CLR)属性的功能,这些服务通常统称为 WPF 属性系统.由 WPF 属 ...
- WPF的依赖属性和附加属性(用法解释较全)
转:https://www.cnblogs.com/zhili/p/WPFDependencyProperty.html 一.引言 感觉最近都颓废了,好久没有学习写博文了,出于负罪感,今天强烈逼迫自己 ...
- wpf 的依赖属性只能在loaded 事件之后才能取到
wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的 InitializeComponent(); 之后取不到 wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的 ...
- WPF 中依赖属性的继承(Inherits)
WPF中依赖属性的值是是可以设置为可继承(Inherits)的,这种模式下,父节点的依赖属性会将其值传递给子节点.例如,数据绑定中经常使用的DataContextProperty: var host ...
- WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性
原文:WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性 如果你要自定义一个图片按钮控件,那么如何在主窗体绑定这个控件上图片的Source呢? ...
- [转]WPF的依赖属性是怎么节约内存的
WPF升级了CLR的属性系统,加入了依赖属性和附加属性.依赖属性的使用有很多好处,其中有两点是我认为最为亮眼的: 1)节省内存的开销; 2)属性值可以通过Binding依赖于其它对象上,这就使得我的数 ...
- WPF利用依赖属性和命令编写自定义控件
以实例讲解(大部分讲解在代码中) 1,新建一个WPF项目,添加一个用户控件之后在用户控件里面添加几个控件用作测试, <UserControl x:Class="SelfControlD ...
- WPF: 只读依赖属性的介绍与实践
在设计与开发 WPF 自定义控件时,我们常常为会控件添加一些依赖属性以便于绑定或动画等.事实上,除了能够添加正常的依赖属性外,我们还可以为控件添加只读依赖属性(以下统称"只读属性" ...
- WPF 自定义依赖属性
原博客地址:http://www.cnblogs.com/DebugLZQ/archive/2012/11/30/2796021.html DependencyObject和Dependen ...
随机推荐
- 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 ...
- 实例分析JVM安全体系:双亲委派、命名空间、保护域、策略
在了解双亲委派模型之前,先了解一下类加载器的概念: 类加载器的作用就是将真实的class文件根据位置将该Java类的字节码装入内存,并生成对应的Class对象.用户可以通过继承ClassLoader和 ...
- (原创)c++11中的日期和时间库
c++11提供了日期时间相关的库chrono,通过chrono相关的库我们可以很方便的处理日期和时间.c++11还提供了字符串的宽窄转换功能,也提供了字符串和数字的相互转换的库.有了这些库提供的便利的 ...
- [iOS]终极横竖屏切换解决方案
[iOS]终极横竖屏切换解决方案 大家的项目都是只支持竖屏的吧?大多数朋友(这其中当然也包括博主),都没有做过横屏开发,这次项目刚好有这个需求,因此把横竖屏相关的心得写成一遍文章供诸位参考. 01.综 ...
- 1. K-Means原理解析
1. K-Means原理解析 2. K-Means的优化 3. sklearn的K-Means的使用 4. K-Means和K-Means++实现 1. 前言 我们在一开始的时候应该就说过,机器学习按 ...
- js实现完美身份证号有效性验证(转)
转载自:http://www.cnblogs.com/lzrabbit/archive/2011/10/23/2221643.html 最近需要对身份证合法性进行验证,实名验证是不指望了,不过原来的验 ...
- Memcaced多站点登录图解
- Eclipse 常用插件安装(最新更新:2016-12-06)
. . . . . Eclipse 用得久了,不停地填充着各种好用的插件.由于我的版本较低,不支持插件导出功能(3.7以上支持),所以把各种体验比较好的插件记录在这里,以便将来全量升级Eclipse时 ...
- StreamingContext.getOrCreate
/** */ object AppRealTime { def main(args: Array[String]): Unit = { ) { println("please input a ...
- 【转载】TCP协议要点和难点全解
说明: 1).本文以TCP的发展历程解析容易引起混淆,误会的方方面面 2).本文不会贴大量的源码,大多数是以文字形式描述,我相信文字看起来是要比代码更轻松的 3).针对对象:对TCP已经有了全面了解的 ...