WPF的依赖项属性
WPF的依赖项属性
属性与事件是.NET抽象模型的核心部分。WPF使用了更高级的依赖项属性(Dependency Property)功能来替换原来.NET的属性,实现了更高效率的保存机制,还添加了附加功能,如属性变更通知以及强制回调、属性值继承(在逻辑树中向下传播默认属性值的能力)以及属性有效性验证等。同时,依赖项属性也是WPF许多重要功能的基础,包括动画、数据绑定以及样式。
依赖项属性的使用基础
使用依赖项属性包括三个部分,定义依赖项属性;注册依赖项属性以及添加属性包装器。
定义依赖项属性,使用三个修饰词,public、static、readonly。数据类型为DependecyProperty,而每一个依赖项属性都会有一个去掉“Property”的CLR属性和他对应,而我们在xaml中访问的都是CLR属性。
注册依赖项属性,这也是依赖项属性的真正含义,在于定义一个DependecyProperty属性后外部访问只能通过其对应的CLR属性,其本质通过DependecyProperty.Register注册,写入了DependecyProperty类中的Hastable中,所有的依赖属性都写入这个哈希表中,哈希表的key值由依赖项属性的name+type组成,保证了key值的唯一性。当需要设置依赖项属性的值时,则会为这个对象创建一个数组,数据类型为EffectiveValueEntry,包含了一个属性的index,DependencyProperty提供了一个方法GetglobalIndex来获取此属性在Hashtable中的位置,value当然就可以在此取出。
注册依赖项属性,在这一步骤中,我们主要负责提供5个要素:
- 属性名
- 属性使用的数据类型
- 拥有该属性的类型
- 一个具有附加属性设置的(Framework)PropertyMetadata对象,可选
- 一个用于验证属性的回调函数 ValidateValueCallback(验证回调),可选
其中的FrameworkPropertyMetadata依赖属性元数据对象,是功能最为丰富的一项要素,元数据中可能包括WPF不同级别的依赖属性的特征,这些特征报告各种服务(如 WPF框架级别的布局引擎和属性继承逻辑)的信息和状态,大致包括以下信息:
- 依赖项属性的默认值
- 更改通知的回调实现的引用
- 强制回调实现的引用
public static DependencyProperty Register(
string name,--依赖项对象的名称
Type propertyType,--属性的类型
Type ownerType,--依赖项对象的所有者类型
PropertyMetadata typeMetadata,--依赖项对象的属性元数据
ValidateValueCallback validateValueCallback--对回调的引用
) public PropertyMetadata(
Object defaultValue,--依赖项对象的默认值
--每当属性的有效值更改时,属性系统都将调用该处理程序实现
PropertyChangedCallback propertyChangedCallback,
--每当属性系统对该属性调用 CoerceValue 时都将调用此处理程序实现
CoerceValueCallback coerceValueCallback
)
--核心级别具有呈现/用户界面影响的非框架属性提供属性元数据
public UIPropertyMetadata(
Object defaultValue,
PropertyChangedCallback propertyChangedCallback,
CoerceValueCallback coerceValueCallback,
bool isAnimationProhibited--是否禁止动画处理,默认为false
)
--框架的属性系统
public FrameworkPropertyMetadata(
Object defaultValue,
--元数据选项标志(FrameworkPropertyMetadataOptions 值的组合)
FrameworkPropertyMetadataOptions flags,
PropertyChangedCallback propertyChangedCallback,
CoerceValueCallback coerceValueCallback,
bool isAnimationProhibited,
--此属性的绑定时使用的 UpdateSourceTrigger
UpdateSourceTrigger defaultUpdateSourceTrigger
)
依赖项属性值变更回调、强制回调以及验证回调的执行顺序如下:
验证:ValidateValueCallback
强制值:CoerceValueCallback
回调:PropertyChangedCallback
添加属性包装器,最后一个步骤是使用传统的.NET属性封装WPF的依赖项属性,封装函数中set、get访问器分别调用了DependecyObjec基类中定义的GetValue()和SetValue()方法。
依赖项属性在数据绑定中的应用

数据绑定中,有5个要素:
- Source:确定哪个对象作为数据源
- Target:确定哪个对象作为目标
- 声明一个Binding实例,用于关联数据
- 数据源的Path,可以是CLR属性也可以是依赖项属性,甚至属性的子属性
- 目标的D.P.,只能是依赖项属性
D.P.的全称是“Dependency Property”,直译过来就是“依赖式属性”,意思是说它自己本身是没有值的,它的值是“依赖”在其它对象的属性值上、通过Binding的传递和转换而得来的。表现在例子里,它就是Target上的被数据所驱动的联动属性了!
其中值得注意的是,当源数据发生改变时,需要通知界面数据变更,并进行界面更新。如若,数据源的Path是一个普通属性,即需要实现INotifyPropertyChanged接口,以此来通知界面变更;而如果数据源的Path是一个依赖项属性,其中INotifyPropertyChanged是为DependencyObject服务的,即可自动发生界面更新事件。
在数据绑定中,也凸显了Winform与WPF的巨大差异,WPF真正意义上实现了 “数据驱动界面” 的模式。换而言之,数据是底层、是心脏,数据变了作为表层的UI就会跟着变、将数据展现给用户;如果用户修改了UI元素上的值,相当于透过UI元素直接修改了底层的数据;数据处于核心地位,UI处于从属地位。数据是程序的发动机(驱动者)、UI成了几乎不包含任何逻辑专供用户观察数据和修改数据的“窗口”(被驱动者)。
WPF的依赖项属性的更多相关文章
- 学习WPF——初识依赖项属性
入门 首先创建一个依赖项属性 然后绑定父容器的DataContext到这个依赖项的实例 接着绑定子元素的属性到依赖项属性(注意Button的Content属性) 程序最终的运行结果: 说明 首先是 ...
- 迟到的 WPF 学习 —— 依赖项属性
本章学习依赖项属性,英文原文 Dependency Property,它是传统 .Net Framework 属性的扩展,是 WPF 的专属,但所幸使用起来和传统属性几乎一样.WPF 元素所提供的大多 ...
- [转]WPF 依赖项属性
from:http://blog.csdn.net/datoumimi/article/details/8033682 ps:环境限制,发的东西一长就会被拦截,所以删了一部分 UI软件中经常会用到大量 ...
- 浅谈WPF依赖项属性
浅谈WPF依赖项属性 0. 引言 依赖项属性虽然在使用上和CLR属性一样,但是它是WPF特有的,不同于CLR属性.只是封装为我们常用CLR的属性,在语法使用上和CLR属性一样.WPF中一些功能:动画, ...
- 如何在 WPF 中获取所有已经显式赋过值的依赖项属性
原文:如何在 WPF 中获取所有已经显式赋过值的依赖项属性 获取 WPF 的依赖项属性的值时,会依照优先级去各个级别获取.这样,无论你什么时候去获取依赖项属性,都至少是有一个有效值的.有什么方法可以获 ...
- WPF中的依赖项属性
Form cnblogs 桂素伟 随着WPF的推广,不得不重新拾起WPF来,因为这块的产品越来越多. 只能跟着MSDN来学了,所以想是在这里记录下学习的过程和对知识的理解. 先从最基本的吧,依赖项属性 ...
- WPF中的依赖项属性(转)
出处:https://www.cnblogs.com/axzxs2001/archive/2010/04/25/1719857.html 随着WPF的推广,不得不重新拾起WPF来,因为这块的产品越来越 ...
- WPF学习系列之二 (依赖项属性)
依赖属性;(dependency property) 它是专门针对WPF创建的,但是WPF库中的依赖项属性都使用普通的.NET属性过程进行了包装.从而可能通过常规的方式使用它们,即使使用他们的代码不 ...
- 在 WPF 中获取一个依赖对象的所有依赖项属性
原文:在 WPF 中获取一个依赖对象的所有依赖项属性 本文介绍如何在 WPF 中获取一个依赖对象的所有依赖项属性. 本文内容 通过 WPF 标记获取 通过设计器专用方法获取 通过 WPF 标记获取 p ...
随机推荐
- 757. Set Intersection Size At Least Two
An integer interval [a, b] (for integers a < b) is a set of all consecutive integers from a to b, ...
- windows 2003 远程桌面无法使用剪贴板共享纯文本的解决方法(亲测可用)
远程桌面无法使用剪贴板共享纯文本的解决方法========================================以下操作须在远程桌面上操作,本地机没用的!================== ...
- oracle为IN OUT变量或OUT变量赋值时提示“表达式''不能用作赋值目标”
是因为IN OUT变量和OUT变量是要输出的,不能赋给它常量值,这样它就不能再被赋值而输出了,所以是禁止赋常量值的,比如''也是常量值,也不可以赋给这两种类型的变量,如果不能把存储过程中的其他变量赋给 ...
- loj#2978. 「THUSCH 2017」杜老师(乱搞)
题面 传送门 题解 感谢yx巨巨 如果一个数是完全平方数,那么它的所有质因子个数都是偶数 我们把每一个数分别维护它的每一个质因子的奇偶性,那么就是要我们选出若干个数使得所有质因子的个数为偶数.如果用线 ...
- 老男孩Day18作业:后台用户管理
一.作业需求: 1.用户组的增删改查 2.用户增删该查 - 添加必须是对话框 - 删除必须是对话框 - 修改,必须显示默认值 3.比较好看的页面 二.博客地址:https://www.cnblogs. ...
- P2561 [AHOI2002]黑白瓷砖
$ \color{#0066ff}{ 题目描述 }$ \(\color{#0066ff}{输入格式}\) 文件中以一行的形式存放一个正整数 n , n ≤ 20 . \(\color{#0066ff} ...
- Git 合并两个不同的仓库
目录 第一步. 下载需要合并的分支 第二步. 添加需要合并远程仓库 第三步. 把base远程仓库中数据抓取到本仓库 第四步. checkount切换到base分支上,命名为 asf 第五步. 合并 总 ...
- 富文本的一般处理方式,document.getElementById('富文本的ID').contentWindow.document.body.innerHTML = '%s'" %(content)
如果套不出来,去问前端开发帮忙吧 哈哈
- (转)取消目录与SVN的关联
第一种方法: 直接.逐级地删除目标目录中的隐藏属性的.svn目录 第二种方法: 如果用的是TortoiseSVN客户端,则先在另外一处建立一个新目录A,右键点住svn目录并拖动到A上松手,在弹出的菜单 ...
- WinForm中如何实现在容器控件中嵌入form窗体(panel与子窗体)
今天在做项目时候遇到一个问题,窗体分为左右两部分,要求在左边栏点击按钮时,右边动态加载窗体最后想到用panel实现,经历几次失败,并查找资料后,终于搞定 说明:如果多次切换需加入 panel.clea ...