依赖属性
依赖属性是WPF中的概念,很多WPF书籍用专门的一章来讲解,初学者经常迷惑,我多次给同事网友解释过。
本文的目的就是想把简单的事情讲清楚,如果你是初学者,欢迎光临。如果你早已熟悉,谢谢光临。
(一)首先我们来看看普通的属性和依赖属性的定义方式:? 【普遍属性】
public
?
class
?MyTextBlock
{ ???? private ? double ?_fontSize? = ? 12 ; ???? public ? double ?FontSize?{? get ?{? return ?_fontSize;?}? set {?_fontSize? = ?value;?}?} }? ? 【依赖属性】?
public?
class
?MyTextBlock?:?DependencyObject?
{ 第一点:要定义一个static readonly的类型为DependencyProperty的FontSizeProperty字段;
第二点:MyTextBlock要直接或间接继承
D
ependencyObject;
第三点:在FontSize属性的get中调用基类(
DependencyObject)的GetValue,在set中调用基类的SetValue;
其中第一点,
FontSizeProperty是
static。这是初学者最容易迷惑的。为什么是
static呢?不管有多少MyTextBlock对象,它们的缺省FontSize都是12,属性名都是“FontSize”
所以FontSizeProperty是
static 。
(二)?依赖属性有什么好处呢?
首先,
节省空间:在一个程序的窗口中会有很多控件,每个控件都有三五十个属性,如果这些属性都是普通属性,那么每个控件就有三五十个字段在内存中,
虽然你根本没有设置过它们,但它们依然存在(占内存)。
FontSize就是例子,一般你很少设置它。这样对内存是一种浪费。而依赖属性
只有你设置了才会在内存中存在,不设置就不会存在。这样就节省了空间,如何节省后面会说到。
再有,依赖属性可以应用动画,双向绑定,Style,还可以从可视化树的祖先中继承值,等等很多好处。? ?
(三)?依赖属性是如何实现这些好处的?
从上面依赖属性的定义方式可以看出,最重要的就是
两个类:
DependencyProperty
和DependencyObject,后者有两个重要的方法(GetValue和SetValue),
我们来模拟一下这两个类的实现。? ? 1. 先从简单的来:DependencyProperty类,代码很简单,如下:
public?
class
?DependencyProperty
{ ?
说明:在这里,
DependencyProperty没做什么事,只是把Name和缺省值保存起来而已。
? ? 2. 接下来,模拟一下DependencyObject类的实现,代码不难,如下:
public?class?DependencyObject?
{ 说明
DependencyObject用了一个字典来存储属性值。如果你从来没设置过MyTextBlock的FontSize,也就从来没调用过
DependencyObject的SetValue方法,字典中也就不会有FontSize的值。从而节省了空间(要知道MyTextBlock会有几十个依赖属性)。
而
DependencyObject的GetValue方法,
根据WPF的优先级规则,分别检查动画值,本地值(字典中的值),Style值,如果都没有就返回缺省值。
也就是说SetValue方法做了很多事情,从而让依赖属性比普通属性强大了很多。
3. 可以写一小段代码验证一下:如果没设置FontSize,则FontSize返回缺省值,代码很难,如下:?
class
?Program
{ ? ?最后,上面只是对DependencyProperty和DependencyObject的猜测。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |