WPF依赖属性2
前一个博客,介绍了依赖属性的基本定义,在定义的过程中register中的的两个参数,并没有传入参数,不知道其是用来干什么的,以下,我们将介绍这两个参数的真正用途FrameworkPropertyMetadata和ValidateValueCallback。 1、FrameworkPropertyMetadata 参数 FrameworkPropertyMetadata是一个重要的参数,其用于配置当前的依赖属性的特性,这个对象的有很多构造函数,我们使用一个比较常用的构造函数 public FrameworkPropertyMetadata( Object defaultValue,FrameworkPropertyMetadataOptions flags,PropertyChangedCallback propertyChangedCallback )
那么FrameworkPropertyMetadata 的作用是什么呢?我们看看这个FrameworkPropertyMetadata对象的几个属性:
我们对几个关键属性进行分析: 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>10) { return "err"; } return baseValue; } } 我们使用这个依赖属性 Example e = new Example(); e.Name = "333"; MessageBox.Show(e.Name); e.Name = "3333333333333"; 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",object baseValue) { string base1 = baseValue.ToString(); if (base1.Length>10) { return "err"; } return baseValue; } private static void OnItemsSourceChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) { MessageBox.Show("finish"); } 调用代码: Example e = new Example(); e.Name = "333"; e.Name = "3333333333333"; 我们可以看到,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(Example),metadata,new ValidateValueCallback(ValidateValue)); } public static DependencyProperty NameProperty; public String Name { set { SetValue(NameProperty,object baseValue) { string base1 = baseValue.ToString(); if (base1.Length>10) { 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后,则程序会抛出异常 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |