zoukankan      html  css  js  c++  java
  • 【转】【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(71, 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 - 71
    ValidateValue - 71

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

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

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

    输出:

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

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

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

    //验证
    static bool ValidateValue(object obj)
    {
        Debug.WriteLine(String.Format("ValidateValue - {0}", obj));
        if ((int)obj == 999)
            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(81, 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 == 999)
                throw new Exception("test");
            return newValue;
        }
    }

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

    var superdobj = new SuperDobj();

    输出:

    ValidateValue - 71
    ValidateValue - 71
    ValidateValue – 81

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

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

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

    输出:

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

    这个结果很有意思。

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

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

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

  • 相关阅读:
    激战运钞车高清在线观看
    AutoLISPDCL各种控件
    你懂的
    AutoLISP简单DCL对话框
    我奋斗了18年不是为了和你一起喝咖啡
    AutoLISP选择集操作
    我奋斗了18年才和你坐在一起喝咖啡
    AutoLISP取得多段线顶点坐标
    AutoLISP确定图纸幅面DCL对话框设计
    AutoLISP对话框DCL控件属性
  • 原文地址:https://www.cnblogs.com/mqxs/p/7675532.html
Copyright © 2011-2022 走看看