wpf企业级开发之深入剖析wpf依赖属性

上传人:第*** 文档编号:37846789 上传时间:2018-04-23 格式:DOCX 页数:6 大小:168.85KB
返回 下载 相关 举报
wpf企业级开发之深入剖析wpf依赖属性_第1页
第1页 / 共6页
wpf企业级开发之深入剖析wpf依赖属性_第2页
第2页 / 共6页
wpf企业级开发之深入剖析wpf依赖属性_第3页
第3页 / 共6页
wpf企业级开发之深入剖析wpf依赖属性_第4页
第4页 / 共6页
wpf企业级开发之深入剖析wpf依赖属性_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《wpf企业级开发之深入剖析wpf依赖属性》由会员分享,可在线阅读,更多相关《wpf企业级开发之深入剖析wpf依赖属性(6页珍藏版)》请在金锄头文库上搜索。

1、深入剖析 WPF 依赖属性 依赖属性基本应用在了 WPF 的所有需要设置属性的元素。依赖属性根据多个提供对象 来决定它的值(可以是动画、父类元素、绑定、样式和模板等) ,同时这个值也能及时响应 变化。所以 WPF 拥有了依赖属性后,代码写起来就比较得心应手,功能实现上也变得非常 容易了。如果没有依赖属性,我们将不得不编写大量的代码。关于 WPF 的依赖属性,主要 有下面三个优点,我们的研究也重点放在这三点上: 1、新功能的引入:加入了属性变化通知,限制、验证等等功能,这样就可以使我们更方便 的实现我们的应用,同时也使代码量大大减少了,许多之前不可能的功能都可以轻松的实 现了。 2、节约内存:在

2、 WinForm 等项目开发中,你会发现 UI 控件的属性通常都是赋予的初始值, 为每一个属性存储一个字段将是对内存的巨大浪费。WPF 依赖属性解决了这个问题,它内 部使用高效的稀疏存储系统,仅仅存储改变了的属性,即默认值在依赖属性中只存储一次。3、支持多个提供对象:我们可以通过多种方式来设置依赖属性的值。同时其内部可以储存 多个值,配合 Expression、Style、Animation 等可以给我们带来很强的开发体验。 在.NET 当中,属性是我们很熟悉的,封装类的字段,表示类的状态,编译后被转化为 对应的 get 和 set 方法(在 JAVA 里面没有属性的概念,通常都是写相应的方法

3、来对字段进 行封装) 。属性可以被类或结构等使用。 一个简单的属性如下,也是我们常用的写法:private string sampleProperty;public string SampleProperty get return sampleProperty; set if (value != null) sampleProperty = value; else sampleProperty = “Knights Warrior!“; 属性是我们再熟悉不过的了,那么究竟依赖属性怎么写呢?依赖属性和属性到底有什么区 别和联系呢?其实依赖属性的实现很简单,只要做以下步骤就可以实现: 第一步: 让

4、所在类型继承自 DependencyObject 基类,在 WPF 中,我们仔细观察框架的类 图结构,你会发现几乎所有的 WPF 控件都间接继承自 DependencyObject 类型。 第二步:使用 public static 声明一个 DependencyProperty 的变量,该变量才是真正的依赖 属性 ,看源码就知道这里其实用了简单的单例模式的原理进行了封装(构造函数私有),只 暴露 Register 方法给外部调用。 第三步:在静态构造函数中完成依赖属性的元数据注册,并获取对象引用,看代码就知道 是把刚才声明的依赖属性放入到一个类似于容器的地方,没有讲实现原理之前,请容许我 先这

5、么陈述。 第四步:在前面的三步中,我们完成了一个依赖属性的注册,那么我们怎样才能对这个依 赖属性进行读写呢?答案就是提供一个依赖属性的实例化包装属性,通过这个属性来实现 具体的读写操作。根据前面的四步操作,我们就可以写出下面的代码:public class SampleDPClass : DependencyObject /声明一个静态只读的DependencyProperty字段public static readonly DependencyProperty SampleProperty; static SampleDPClass() /注册我们定义的依赖属性Sample SamplePr

6、operty = DependencyProperty.Register(“Sample“, typeof(string), typeof(SampleDPClass), new PropertyMetadata(“Knights Warrior!“, OnValueChanged); private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) /当值改变时,我们可以在此做一些逻辑处理 /属性包装器,通过它来读取和设置我们刚才注册的依赖属性public string S

7、ample get return (string)GetValue(SampleProperty); set SetValue(SampleProperty, value); 总结:我们一般.NET 属性是直接对类的一个私有属性进行封装,所以读取值的时候,也就 是直接读取这个字段;而依赖属性则是通过调用继承自 DependencyObject 的 GetValue()和 SetValue 来进行操作,它实际存储在 DependencyProperty 的一个 IDictionary 的键-值配对字 典中,所以一条记录中的键(Key)就是该属性的 HashCode 值,而值(Value)则是我们

8、注册的 DependencyProperty。六. 依赖属性的优先级由于 WPF 允许我们可以在多个地方设置依赖属性的值,所以我们就必须要用一个标 准来保证值的优先级别。比如下面的例子中,我们在三个地方设置了按钮的背景颜色,那 么哪一个设置才会是最终的结果呢?是 Black、Red 还是 Azure 呢?Click通过前面的简单介绍,我们了解了简单的依赖属性,每次访问一个依赖属性,它内部会按照下面的顺序由高到底处理该值。详细见下图由于这个流程图偏理想化,很多时候我们会遇到各种各样的问题,这里也不可能一句话、 两句话就能够把它彻底说清楚,所以我们就不过多纠缠。等遇到问题之后要仔细分析,在 找到原

9、因之后也要不断总结、举一反三,只有这样才能逐渐提高。七. 依赖属性的继承依赖属性继承的最初意愿是父元素的相关设置会自动传递给所有层次的子元素 ,即元 素可以从其在树中的父级继承依赖项属性的值。这个我们在编程当中接触得比较多,如当 我们修改窗体父容器控件的字体设置时,所有级别的子控件都将自动使用该字体设置 (前 提是该子控件未做自定义设置),如下面的代码:没有继承自Window的FontSize,StatusbarWindow.FontSize 设置会影响所有的内部元素字体大小,这就是所谓的属性值继承,如 上面代码中的第一个 Label 没有定义 FontSize ,所以它继承了 Window.

10、FontSize 的值。但一 旦子元素提供了显式设置,这种继承就会被打断,如第二个 Label 定义了自己的 FontSize, 所以这个时候继承的值就不会再起作用了。这个时候你会发现一个很奇怪的问题:虽然 StatusBar 没有重写 FontSize,同时它也是 Window 的子元素,但是它的字体大小却没有变化,保持了系统默认值。那这是什么原因 呢?作为初学者可能都很纳闷,官方不是说了原则是这样的,为什么会出现表里不一的情 况呢?其实仔细研究才发现并不是所有的元素都支持属性值继承。还会存在一些意外的情 况,那么总的来说是由于以下两个方面: 1、有些 Dependency 属性在用注册的时

11、候时指定 Inherits 为不可继承,这样继承就会失效 了。 2、有其他更优先级的设置设置了该值,在前面讲的的“依赖属性的优先级”你可以看到具 体的优先级别。这里的原因是部分控件如 StatusBar、Tooptip 和 Menu 等内部设置它们的字体属性值以 匹配当前系统。这样用户通过操作系统的控制面板来修改它们的外观。这种方法存在一个 问题:StatusBar 等截获了从父元素继承来的属性,并且不影响其子元素。比如,如果我们 在 StatusBar 中添加了一个 Button。那么这个 Button 的字体属性会因为 StatusBar 的截断而 没有任何改变,将保留其默认值。所以大家在

12、使用的时候要特别注意这些问题。 前面我们看了依赖属性的继承,当我们自定义的依赖属性,应该如何处理继承的关系呢?public class MyCustomButton : Button static MyCustomButton() /通过MyStackPanel依赖属性MinDateProperty的AddOwner方式实现继承,注意FrameworkPropertyMetadataOptions的值为InheritsMinDateProperty = MyStackPanel.MinDateProperty.AddOwner(typeof(MyCustomButton), new Frame

13、workPropertyMetadata(DateTime.MinValue, FrameworkPropertyMetadataOptions.Inherits); public static readonly DependencyProperty MinDateProperty; public DateTime MinDate get return (DateTime)GetValue(MinDateProperty); set SetValue(MinDateProperty, value); public class MyStackPanel : StackPanel static M

14、yStackPanel() /我们在MyStackPanel里面注册了MinDate,注意FrameworkPropertyMetadataOptions的值为InheritsMinDateProperty = DependencyProperty.Register(“MinDate“, typeof(DateTime), typeof(MyStackPanel), new FrameworkPropertyMetadata(DateTime.MinValue, FrameworkPropertyMetadataOptions.Inherits); public static readonly DependencyProperty MinDateProperty; public DateTime MinDate get return (DateTime)GetValue(MinDateProperty); set SetValue(MinDateProperty, value); 那么就可以在 XAML 中进行使用了最后的效果如下文章来自学 IT 网:http:/

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号