
依懒属性是WPF推出的概念,使用它的好处很多,这一点在Silverlight里也得到了继承,由于这个概念比较抽象,它不同于.NET中一般的属性类型,所以我个人整理了一些关于依赖属性的文章希望对大家有用。
WPF揭秘:| 依赖属性(Dependency PropertIEs) 通过该方法的不同重载,我们可以有选择地传递处理自定义属性元数据,也可以编写那些用于处理属性值变更、强制转换(coerce)和验证(valIDate)的回调方法。button在其静态构造方法中调用了Register方法的一种重载,并向其提供了依赖属性的默认值(false),并且为处理变更通知(change notification)附加了一个委托。 变更通知 属性值的继承 属性值继承(简称属性继承)与传统的面向对象继承不同,它是指属性值可以沿着元素树向下传递的过程。 例:在Window元素上设置属性 <Window x:Class="Test.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" title="WPF揭秘" SizetoContent="WIDthAndHeight" FontSize="30" FontStyle="Italic" Background="OrangeRed"> <StackPanel> <Label FontWeight="Bold" FontSize="20" Foreground="White"> WPF揭秘(版本3.0) </Label> <Label>(C)2006 SAMS 出版集团</Label> <Label>已安装的章节:</Label> <ListBox> <ListBoxItem>第一章</ListBoxItem> <ListBoxItem>第二章</ListBoxItem> </ListBox> <StackPanel OrIEntation="Horizontal" HorizontalAlignment="Center"> <button MinWIDth="75" margin="10">Help</button> <button MinWIDth="75" margin="10">OK</button> </StackPanel> <Statusbar>您已经注册了本产品。</Statusbar> </StackPanel> </Window> 下图展示了以显式方式设置Window元素的FontSize和FontStyle依赖属性后,整个窗体的变化情况。 为这两个属性设置的值将会沿着元素树向下传递,并被相应的子元素继承(即将子元素的对应属性也被设定为这个值)。上例中,button、Label和ListBoxItem都受到了影响,但由于第一个Label显式设置了FontSize,从而其字体大小未受影响。值得注意的是,Statusbar中的文本并没有受到这两个值的影响,尽管它与其它控件相同,也包含这两个属性。由于以下两种原因,属性值的继承显得有些微妙: (1)并不是所有的依赖属性都参与属性值的继承(依赖属性可以通过向DependencyProperty.Register传递FrameworkPropertyMatadataOptions.inherits来选择是否参与继承) (2)可能存在更高优先级的属性设定源(稍后解释) Statusbar显示的结果由第二种原因导致的。一些如Statusbar、Menu和tooltip控件的内部将它们的字体属性设定为匹配当前系统的设置。这种结果有些令人迷惑,因为这样的控件阻止了继承属性值沿着元素树继续传递。例如,当我们在Statusbar中加入一个button作为其逻辑子元素,那么button的FontSize和FontStyle都将保持默认值,这与处于Statusbar之外的那些button不同。 属性值继承本来是用来 *** 作元素树的,但是它也可以用于在其它情境。例如,属性值可以传递到某个XML意义上的子元素,而这个子元素并非逻辑树或视觉树的子元素。这些伪子元素可以是某个元素的触发器,也可是任意属性值,只要它是一个从Freezable派生的对象就可以。(暂不明) 对多种提供器的支持
"3">ShirtTypes newShirtType = (d as Shirt).ShirtType; |
Silverlight学习笔记:“依赖对象”和“依赖属性”的介绍:
| 学习silverlight没什么门路,跑了几趟书店都没买到sl的书,真慢。今天装了vs2008,于是打开vs的对象浏览器,看看sl里面的类库都是什么德行。 那么先从xaml文档的根节点元素开始看吧~~~ 查看之下还真是看不出什么所以然~~~ 就这个图能看出什么端倪?所以说要搞清楚一个类库还是得先从她的身家背景开始看起... Canvas的一家 据说谁的祖先都是从单细胞(object)发展而来的,那么从第二代开始看.... 二代目: Findname是通过姓名找孩子(说也奇怪,到DependencyObject还没有Children这个属性,也没有WPF中独生子女的Content属性,这是干什么用的?找谁家的孩子?),下面的name是自己本身的名字……其它的,看不懂……先放着…… 第三代: 由于子元素存在于父元素“体内”,点击子元素实际上也应该“通知”父元素,所以鼠标事件是会向上传递的。 讲个故事吧,爸爸和儿子守着一条小道,儿子在前。前面跑来一只兔子(或者是一只很身手很差的老鼠),那么如果儿子捕获了兔子(儿子很厉害,想捉一定会捉住,也就是执行CaptureMouse()返回true),那么父亲那里执行CaptureMouse()肯定会返回false了,除非儿子那里抓了又放了,就是ReleaseMouseCapture()了。 情况如同下面的代码:(txt是一个TextBlock) public partial class Page : Canvas 第四代了: 很多很复杂…… 第五代了: 六代: Children属性管理子元素,它是一个MS.Internal.Collection<Visual>类型的子类 最后到了Canvas 在Penel的基础上增加了2个依赖属性 现在没得逃避了。 而依赖对象是怎么工作的呢?其实打字到这一行之前我也不清楚,只是以前看过一篇WPF的关于依赖属性的文章,留下一点模糊的记忆,然后刚才回去又仔细查阅了对象信息,发现原来DependencyObject类的两个重要方法有玄机: 其实就是DependencyObject里面有一个隐藏的“字典”对象,通过父元素调用的,比如Canvas调用了TextBlock的SetValue方法 this.Findname("aTextBlock").SetValue(Canvas.leftProperty,20); 相当于,父对象把一个值(这里是20)存进了子对象的“字典”里,而父亲的(静态只读成员)leftProperty就是那把钥匙,也就是Key!!!!哈哈哈 ,终于理解了。那把钥匙可以打开所有子对象的“字典”,取出匹配于leftProperty的值。 foreach (Visual child in this.Children) { 这也就是为什么脚本可以这么写<TextBlock Canvas.left="20">,而TextBlock类却没有一个Canvas.top属性的原因了,而xaml中声明式的指定Canvas.left,是由xaml解析引擎的时候自动完成的。 了解了依赖属性的工作方式后,很容易通过这个特点来使用xaml标记用户自定义控件…… 就这样了。。。 续: 经过继续研究,发现所谓“依赖属性”的作用实在“博大”,它可以使用于本对象以外的"包装类"对其包装,如xaml解析对象通过调用SetValue对UI对象进行初始化;渲染引擎使用GetValue取得它与父元素相依赖的属性值(如在渲染Canvas的子对象时需要子元素中Canvas.top属性的值) “依赖属性集”既可以放本身需要的属性,也可以放其他元素的所需要的信息集。以“键”和“值”的方式存取。。。。很方便,很强大! |
| 依赖属性(Dependency Property) .NET Framework 3.0引入了一个新的属性类型叫依赖属性,WPF,WF都在使用依赖属性用来实现样式化,数据绑定等.我们更多的使用依赖属性是为了让父元素的属性值在逻辑树上慢慢的传递到其子元素中,从而可以在整个可是父元素的逻辑子元素中共享属性值.WF就是依靠依赖属性来在工作流中的各Activity间传递属性值的. 所以,依赖属性内建的传递变更通知的能力是其最大特征. 如果你想让属性在一个包含内容子控件树的整个逻辑控件树中都有效并共享值时,你仅仅只需要将这个属性声明为依赖属性即可,WPF会通过内建的架构来支持属性的共享. 而在工作流中我们经常需要用到依赖属性,它保证了在一个工作流实例中,多个组件共享了同一个值. 幸运的是在WPF中大部分空间的属性都是依赖属性,这让我们应用时非常方便,而你并不需要着后边发生了什么。 依赖属性的实现 依赖属性其实也是普通的.NET属性,只是通过DependencyProperty.Register方法将普通的.NET属性注册为依赖属性。在依赖属性的声明中,其实对应的普通.NET属性并不是必需的,因为其内部的GetValue和SetValue方法是公开的,依赖属性的使用者可以通过调用GetValue/SetValue而放弃对普通.NET属性的依赖。但建立在普通.NET熟悉之上更符合我们通常的做法,而且这样有利于在XAML中设置属性。 下面的代码展示了定义依赖属性的通常做法:
在上面的示例代码中是标准的实现依赖属性定义的方法,这里需要注意的是依赖属性始终是定义在普通.NET属性之上的用Register静态方法注册的特殊属性,即便这里的.NET属性(如IsDefault属性)不是必需的。另一个需要注意的地方是,通过声明依赖属性,我们多了一个控制属性改变时的回调方法(即便这同样可以通过声明委托和事件来定义,但这里我们什么都没做,为什么不用呢?),这样的好处是我们可以在属性改变的时候做些我们想做的事情,而我们却省去了手动声明事件的任务。其实回调函数的存在是为了让我们保证在属性包装器中(IsDefault属性)仅仅使用标准的GetValue/SetValue而不用任何其他逻辑,转而将自定义逻辑写入回调函数--这样做是为了遵循WPF的统一设计原则,让XAML 设置属性与使用过程式代码设置属性保持一致。 触发器 依赖属性的实现让我们可以在一个局部范围内保持属性值的共享,这样的好处是对于内存的节约,因为GetValue/SetValue内部使用了高效的稀疏存储系统. 前边提到过,依赖属性的一大特征是变更通知,意思就是当某些依赖属性的只改变了,WPF就会更具属性的元数据触发一系列动作. WPF中有三种方式来实现这样的变更通知: 属性触发器: 在属性发生改变时执行自定义动作,而不用改任何过程代码。 数据触发器: 当普通.NET属性的值改变时调用自定义动作。 事件触发器: 当路由事件被触发时调用自定义动作。 属性触发器(Trigger) 当某个属性有一个特定的值时,属性触发器会执行一个Setter的集合来设置相关对象的属性,而当属性失去这个值的时候,属性触发器会撤消该Setter集合. 这样的好处是大大简化了我们用声明事件的办法来处理满足一定条件时的逻辑,我们在XAML中就可以完成相应的简单逻辑(如果复杂还是需要过程式代码)。
对于属性触发器的应用我们更多的还可以通过自定义验证规则来实现对样式和tooltip的自动设置。 数据触发器(Data Trigger) 数据触发器与属性触发器几乎一样,只是数据触发器可以由任何.NET属性触发,而不仅仅是依赖属性.为了使用数据触发器,可向Triggers集合中添加DataTrigger对象然后指定属性/值对.同时可以用Binding来指定相关属性而不仅仅是属性名. 以下示例通过binding指定当自己的值为Disabled的时候将自己禁用. 注意:Text属性不是依赖属性.
事件触发器(Event Trigger) 当一个已选择的事件产生时事件触发器会被激活.这个事件由触发器的RouteEvent属性指定,他在Action集合中包含一个或多个动作(从抽象类TriggerAction继承来的对象). 下边的示例展示了在button的Click事件被触发时执行DoubleAnimation动作.
属性值继承 附加属性(Attached Property) 附加属性也属于XAML为了扩展其能力的一种,它提供了让用户在父属性里设置自己没有的子属性值的能力。而在应用附加属性时,通常它也可以体现WPF中属性传递的优点:例如,当你给一个Panel中的某类元素设置了附加属性,那么在不显式声明相关属性值(重写)的情况下,此类元素共同从父元素得到这个值。 作为附加属性,之所以说是扩展了XAML的应用是因为它提供了通过父元素来设置子元素并在其可视树范围内默认共享的能力。那么我们可以通过给Panel来设置TextElement.FontSize属性来让所有在这个Panel下的拥有TextElement.FontSize相关属性的控件自动拥有这个值,而不需要我们挨个对所有此类空间设置。例如:
在上述的例子中,由于在StackPanel中设置了TextElement.FontSize,所以在它的内部的可视控件自动有用这个属性:TextBlock,button都会以FontSize=10来显示。 |
以上是内存溢出为你收集整理的WPF和Silverlight依懒属性文章杂乱整理全部内容,希望文章能够帮你解决WPF和Silverlight依懒属性文章杂乱整理所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)