前一个博客,介绍了依赖属性的基本定义,在定义的过程中register中的的两个参数,并没有传入参数,不知道其是用来干什么的,以下,我们将介绍这两个参数的真正用途FrameworkPropertyMetadata和ValidateValueCallback。

1、FrameworkPropertyMetadata 参数

FrameworkPropertyMetadata是一个重要的参数,其用于配置当前的依赖属性的特性,这个对象的有很多构造函数,我们使用一个比较常用的构造函数

public FrameworkPropertyMetadata( Object defaultValue, FrameworkPropertyMetadataOptions flags, PropertyChangedCallback propertyChangedCallback )

那么FrameworkPropertyMetadata 的作用是什么呢?我们看看这个FrameworkPropertyMetadata对象的几个属性:

编号 名称 说明
1 AffectsArrange 获取或设置一个值,该值指示依赖项属性是否会影响布局引擎运行期间的排列处理过程。
2 AffectsMeasure 获取或设置一个值,该值指示依赖项属性是否会影响布局引擎运行期间的测量处理过程。
3 AffectsParentArrange 获取或设置一个值,该值指示依赖项属性是否会影响布局引擎运行期间其父元素布局的排列处理过程。
4 AffectsParentMeasure 获取或设置一个值,该值指示依赖项属性是否会影响布局引擎运行期间其父元素布局的测量处理过程。
5 AffectsRender 获取或设置一个值,该值指示依赖项属性是否会以某种方式(这种方式不会具体影响排列或测量,但将请求重绘)对常规布局造成潜在影响。
6 BindsTwoWayByDefault 获取或设置一个值,该值指示默认情况下属性是否双向绑定。
7 CoerceValueCallback 获取或设置对此元数据中所指定 CoerceValueCallback 实现的引用
8 DefaultUpdateSourceTrigger 获取或设置在应用具有该元数据的属性的绑定时要使用的 UpdateSourceTrigger 的默认值,这些绑定的 UpdateSourceTrigger 设置为 Default。
9 DefaultValue 获取或设置依赖项属性的默认值.(继承自 PropertyMetadata。)
10 IsAnimationProhibited 获取或设置一个值,声明是否应在应用了包含元数据实例的依赖项对象上禁用动画。(继承自 UIPropertyMetadata。)
11 IsDataBindingAllowed 获取一个值,该值指示依赖项属性是否支持数据绑定。
12 IsNotDataBindable 获取或设置一个值,该值指示依赖项属性是否支持数据绑定。
13 IsSealed 获取一个值,该值确定是否已通过某种方式将元数据应用于属性,从而导致该元数据实例变为不可变状态。(继承自 PropertyMetadata。)
14 Journal 获取或设置一个值,该值指示该属性是否包含应用程序可以或应该存储为日记实现一部分的日记信息。
15 OverridesInheritanceBehavior 获取或设置一个值,该值指示属性值继承计算是否应跨越元素的逻辑树中的某些内容边界。
16 PropertyChangedCallback 获取或设置对此元数据中所指定 PropertyChangedCallback 实现的引用。 (继承自 PropertyMetadata。)
17 SubPropertiesDoNotAffectRender 获取或设置一个值,该值指示依赖项属性的子属性是否影响包含对象的呈现。

我们对几个关键属性进行分析:

AffectsArrange、AffectsMeasure、AffectsParentArrange、AffectsParentMeasure、AffectsRender。

五个属性,主要是用于定义当前依赖属性的改变,是否影响控件调整。如果设置AffectsArrange=true,属性的变化会造成控件重新排列。

BindsTwoWayByDefault: 指定属性是否是双向绑定,这个会在绑定的地方详细讲解

CoerceValueCallback:一个回调函数,用于在验证依赖属性之前尝试“纠正”属性值。我们可以简单的案例说明:

class Example:DependencyObject
     {
         static Example()
         {
             FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
             metadata.DefaultValue = "example";
             metadata.CoerceValueCallback = new CoerceValueCallback(CoerceMaxValue);
             NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Example), metadata);
         }
        public static DependencyProperty NameProperty;
         public String Name {
            set { SetValue(NameProperty, value); }
             get { return (string)GetValue(NameProperty); }
         }
        private static  object CoerceMaxValue(DependencyObject d, object baseValue)
         {
             string base1 = baseValue.ToString();
             if (base1.Length>)
             {
                 return "err";
             }
             return baseValue;
         }
     }

我们使用这个依赖属性

Example e = new Example();
e.Name = "";
MessageBox.Show(e.Name);
e.Name = "";
MessageBox.Show(e.Name);

我们可以到,第一个弹出框显示333,第二个弹出框,显示err,所以CoerceValueCallback的作用就是验证传入的依赖属性,并且可以修改属性,并且可以用来修改类型,可以把字符串red修改为color对象。

IsAnimationProhibited、IsDataBindingAllowed、IsSealed、IsSealed、SubPropertiesDoNotAffectRender:

标记依赖属性的一些特性,比如是否可以应用与动画或者数据绑定等。

PropertyChangedCallback:

属性,这个属性比较有用,代表属性发生变化的时候,调用的函数,这个函数在CoerceValueCallback函数调用之后调用,代表属性已经确定完成的最后一个步骤,我们简单案例如下:

static Example()
        {
            FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
            metadata.DefaultValue = "example";
            metadata.CoerceValueCallback = new CoerceValueCallback(CoerceMaxValue);
            metadata.PropertyChangedCallback = new PropertyChangedCallback(OnItemsSourceChanged);
            NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Example), metadata);
        }
       public static DependencyProperty NameProperty;
        public String Name {
           set { SetValue(NameProperty, value); }
            get { return (string)GetValue(NameProperty); }
        }
       private static  object CoerceMaxValue(DependencyObject d, object baseValue)
        {
            string base1 = baseValue.ToString();
            if (base1.Length>)
            {
                return "err";
            }
            return baseValue;
        }
       private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            MessageBox.Show("finish");
        }

调用代码:

Example e = new Example();
e.Name = "";
e.Name = "";

我们可以看到,finish被弹出了两次,每次属性改变都会调用此函数。

2、ValidateValueCallback参数

  在定义任何类型属性的时候,都需要面对错误设置属性的情况,对于传统属性来说,可以通过get/set方法中,对属性进行验证,但是wpf虽然也有get/set,但是其设置方式和传统属性完全不同,无法通过get/set中进行验证,那么wpf提供FrameworkPropertyMetadata中的回调函数进行判断,在CoerceValueCallback 中对值进行判断合法性,但在设置给对象之前,还需要调用ValidateValueCallback函数,最终确定是否修改值,ValidateValueCallback回调会返回true和false,赋值和不赋值,假如赋值发生修改,则会调用PropertyChangedCallback回调,基本案例如下:

class Example:DependencyObject
   {
       static Example()
       {
           FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
           metadata.DefaultValue = "example";
           metadata.CoerceValueCallback = new CoerceValueCallback(CoerceMaxValue);
           metadata.PropertyChangedCallback = new PropertyChangedCallback(OnItemsSourceChanged);
           NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Example), metadata,new ValidateValueCallback(ValidateValue));
       }
      public static DependencyProperty NameProperty;
       public String Name {
          set { SetValue(NameProperty, value); }
           get { return (string)GetValue(NameProperty); }
       }
      private static  object CoerceMaxValue(DependencyObject d, object baseValue)
       {
           string base1 = baseValue.ToString();
           if (base1.Length>)
           {
               return "err";
           }
           return baseValue;
       }
       static bool ValidateValue(object obj)
       {
           if (obj.ToString() == "err") { return false; }
           return true;
       }
       private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
       {
           MessageBox.Show("finish");
       }
   }

代码经过以上的修改,我们发现finish只会弹出一次,返回false后,则程序会抛出异常

WPF依赖属性2的更多相关文章

  1. WPF依赖属性详解

    WPF依赖属性详解 WPF 依赖属性 英文译为 Dependency Properties,是WPF引入的一种新类型的属性,在WPF中有着极为广泛的应用,在WPF中对于WPF Dependency P ...

  2. WPF自学入门(五)WPF依赖属性

    在.NET中有事件也有属性,WPF中加入了路由事件,也加入了依赖属性.最近在写项目时还不知道WPF依赖属性是干什么用的,在使用依赖项属性的时候我都以为是在用.NET中的属性,但是确实上不是的,通过阅读 ...

  3. WPF依赖属性值源(BaseValueSource)

    原文:WPF依赖属性值源(BaseValueSource)   WPF依赖属性提供一个机制,可以获取依赖属性提供值的来源 其以BaseValueSource枚举表示 1.Default public ...

  4. WPF依赖属性(续)(3)依赖属性存储

    原文:WPF依赖属性(续)(3)依赖属性存储          在之前的两篇,很多朋友参与了讨论,也说明各位对WPF/SL计数的热情,对DP系统各抒已见,当然也出现了一些分歧. 以下简称DP为依赖属性 ...

  5. WPF依赖属性(续)(1)

    原文:WPF依赖属性(续)(1)                 之前有写过几篇文章,详细地介绍了依赖属性的基本使用方法,如果你不想了解其内部实现机制的话,那么通过那两篇文章的介绍,足以应付平时的应用 ...

  6. WPF依赖属性(续)(2)依赖属性与附加属性的区别

    原文:WPF依赖属性(续)(2)依赖属性与附加属性的区别        接上篇,感谢各位的评论,都是认为依赖属性的设计并不是为了节省内存,从大的方面而讲是如此.样式,数据绑定,动画样样都离不开它.这篇 ...

  7. 监听WPF依赖属性

    原文:监听WPF依赖属性 当我们使用依赖属性的时候,有时需要监听它的变化,这在写自定义控件的时候十分有用, 下面介绍一种简单的方法.   如下使用DependencyPropertyDescripto ...

  8. WPF依赖属性的正确学习方法

    前言 我在学习WPF的早期,对依赖属性理解一直都非常的不到位,其恶果就是,我每次在写依赖属性的时候,需要翻过去的代码来复制黏贴. 相信很多朋友有着和我相同的经历,所以这篇文章希望能帮助到那些刚刚开始学 ...

  9. WPF 依赖属性前言

    WPF 依赖属性前言 ​ 在.net中,我们可以属性来获取或设置字段的值,不需要在编写额外的get和set方法,但这有一个前提,那就是需要在对象中拥有一个字段,才能在此字段的基础上获取或设置字段的值, ...

  10. WPF 依赖属性

    依赖属性,简单的说,在WPF控件应用过程中,界面上直接可以引用的属性 如:<Button Content="aaa"></Button> Content称为 ...

随机推荐

  1. 一次浴火重生的MySQL优化(EXPLAIN命令详解)

    一直对SQL优化的技能心存无限的向往,之前面试的时候有很多面试官都会来一句,你会优化吗?我说我不太会,这时可能很多人就会有点儿说法了,比如会说不要使用通配符*去检索表.给常常使用的列建立索引.还有创建 ...

  2. 使用 Router 实现的模块化,如何优雅的回到主页面

    使用 Router 实现的模块化,如何优雅的回到主页面 版权声明: 本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有. 未经允许,不得转载. 一.前言 现在越来越多的 App ...

  3. python-冒泡排序,升序、降序

    冒泡排序 这个算法的名字由来是因为越大的元素会经交换慢慢浮'到数列的顶端. 冒泡排序的基本思想:重复走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来,直到没有再需要交换,完成排序 ...

  4. 贡献你的代码,将jar包发布到Maven中央仓库以及常见错误的解决办法

    前几天将自己的日志工具发布到了Maven中央仓库中.这个工具本省没有多少技术含量,因为是修改别人的源代码实现的,但是将jar发布到Maven仓库却收获颇丰,因为网上有些教程过时了,在此分享下自己发布j ...

  5. Xamarin.Forms(一) Visual Studio 连接安卓模拟器(逍遥安卓)

    刚开始学习Xamarin.Forms的时候总是比较困难的,连接安卓模拟器就花了我好长时间,后来在网上找到了方法: 1.打开adb.exe所在目录: 如:cd F:\Android\android-sd ...

  6. Koa框架教程,Koa框架开发指南,Koa框架中文使用手册,Koa框架中文文档

    我的博客:CODE大全:www.codedq.net:业余草:www.xttblog.com:爱分享:www.ndislwf.com或ifxvn.com. Koa -- 基于 Node.js 平台的下 ...

  7. HTML <img>标签 创建图像映射

    初级前端一枚 下面代码是在图片上创建图像映射 自己整理了下 做个笔记 希望也可以帮助后来学习的朋友! <map name="planetmap"> <area s ...

  8. cocoa pods 命令不执行command not found

    bogon:~ mrbtios01$ cd Desktop/改版app/lingMoney新改版的 //当出现如下问题时: bogon:lingMoney新改版的 mrbtios01$ vim pod ...

  9. [stm32F429-DISCO-HAL] 1.先说说关于stm32Cube的一些事情。然后,Start with it...

    目前,我觉得STM32CUBE最大的方便在于,可以使用STM32CubeMX软件来图形化配置外设.首先贴出官网的PDF,Getting started with STM32CubeF4 firmwar ...

  10. pwnable.kr memcpy之write up

    // compiled with : gcc -o memcpy memcpy.c -m32 -lm #include <stdio.h> #include <string.h> ...