Silverlight学习笔记:“依赖对象”和“依赖属性”

Silverlight学习笔记:“依赖对象”和“依赖属性”,第1张

概述学习silverlight没什么门路,跑了几趟书店都没买到sl的书,真慢。今天装了vs2008,于是打开vs的对象浏览器,看看sl里面的类库都是什么德行。 那么先从xaml文档的根节点元素开始看吧~~~ 查看之下还真是看不出什么所以然~~~ 就这个图能看出什么端倪?所以说要搞清楚一个类库还是得先从她的身家背景开始看起... Canvas的一家 据说谁的祖先都是从单细胞(object)发展而来的,那

学习silverlight没什么门路,跑了几趟书店都没买到sl的书,真慢。今天装了vs2008,于是打开vs的对象浏览器,看看sl里面的类库都是什么德行。

那么先从xaml文档的根节点元素开始看吧~~~ 查看之下还真是看不出什么所以然~~~


就这个图能看出什么端倪?所以说要搞清楚一个类库还是得先从她的身家背景开始看起...

Canvas的一家


据说谁的祖先都是从单细胞(object)发展而来的,那么从第二代开始看....


二代目:
System.windows.DependencyObject “依赖对象”  一个抽象类,好像没什么好看的。


Findname是通过姓名找孩子(说也奇怪,到DependencyObject还没有Children这个属性,也没有WPF中独生子女的Content属性,这是干什么用的?找谁家的孩子?),下面的name是自己本身的名字……其它的,看不懂……先放着……


第三代:
System.windows.Media.Visual    “可视对象” 也是抽象类   
 
增加了2个方法,捕捉"鼠标事件"和释放"鼠标事件"

由于子元素存在于父元素“体内”,点击子元素实际上也应该“通知”父元素,所以鼠标事件是会向上传递的。
但是用户点击父元素的任意一部分,父元素怎么知道到底有没有点到什么子元素啊?总之,就是为了弄清楚咯吱哪里该谁笑的疑惑,就弄了这两个方法。总的来看,可能为了兼容1.0吧,封装的好差的说。本来应该由事件参数做的事情变成sender做了,不过从行为来看,这样也合理了,总之就是不同于.net winform。

讲个故事吧,爸爸和儿子守着一条小道,儿子在前。前面跑来一只兔子(或者是一只很身手很差的老鼠),那么如果儿子捕获了兔子(儿子很厉害,想捉一定会捉住,也就是执行CaptureMouse()返回true),那么父亲那里执行CaptureMouse()肯定会返回false了,除非儿子那里抓了又放了,就是ReleaseMouseCapture()了。

情况如同下面的代码:(txt是一个TextBlock)

     public   partial   class  Page : Canvas
    {
        
public   voID  Page_Loaded( object  o, EventArgs e)
        {
            InitializeComponent();
            
this .MouseleftbuttonDown  +=   new  MouseEventHandler(Page_MouseleftbuttonDown);
            txt.MouseleftbuttonDown 
+=   new  MouseEventHandler(TextBlock_MouseleftbuttonDown);
        }
        
voID  Page_MouseleftbuttonDown( object  sender, MouseEventArgs e)
        {
            txt.Text 
+=  (sender  as  Visual).CaptureMouse().ToString();
            
// 如果点击了TextBlock,结果会是false,因为在TextBlock那已经执行了CaptureMouse()
            
// 如果点击了Canvas的其他部分(如空白部分),结果会是true,因为变成是第一手处理了
        }
        
voID  TextBlock_MouseleftbuttonDown( object  sender, MouseEventArgs e)
        {
            txt.Text 
+=  (sender  as  Visual).CaptureMouse().ToString(); // 因为是第一个执行,会是true
            
            
// (sender as Visual).ReleaseMouseCapture();如果这句被执行了(放开兔子),那么Canvas那里就会是true了
        }
    }

第四代了:
System.windows.UIElement  “用户对象” 还是抽象类  增加一堆事件和属性、依赖属性。

很多很复杂……

第五代了:
System.windows.FrameworkElement “框架元素” 抽象的
增加了重要的“父元素”属性 以及外观属性:高 和 宽

六代:
子承父业,到了System.windows.Controls.Panel,长成了容器级的元素


Children属性管理子元素,它是一个MS.Internal.Collection<Visual>类型的子类


最后到了Canvas 在Penel的基础上增加了2个依赖属性

现在没得逃避了。
所谓依赖属性,就是通过被依赖的对象起作用,就如一个TextBlock对象是Canvas对象的子对象,那么Canvas对象就通过Canvas.left对TextBlock起管理的作用,但离开了Canvas,这个属性也就没有作用了。就好像“母亲”拥有的“母爱”依赖于“孩子的存在”而存在,当孩子离开了母亲,这种“爱”也就无从谈起了。
依赖关系,也就是WPF中“视觉元素”相互依赖的奥义了。而所有的依赖属性,都是父元素与子元素之前牵扯不断的关系,而这些属性都是为“视觉体现”而服务的。

(以上是我自己的解释)

而依赖对象是怎么工作的呢?其实打字到这一行之前我也不清楚,只是以前看过一篇WPF的关于依赖属性的文章,留下一点模糊的记忆,然后刚才回去又仔细查阅了对象信息,发现原来DependencyObject类的两个重要方法有玄机:


其实就是DependencyObject里面有一个隐藏的“字典”对象,通过父元素调用的,比如Canvas调用了TextBlock的SetValue方法
this.Findname("aTextBlock").SetValue(Canvas.leftProperty,20);
相当于,父对象把一个值(这里是20)存进了子对象的“字典”里,而父亲的(静态只读成员)leftProperty就是那把钥匙,也就是Key!!!!哈哈哈 ,终于理解了。那把钥匙可以打开所有子对象的“字典”,取出匹配于leftProperty的值。

            foreach (Visual child in this .Children) {
                
double left = (double )child.GetValue(Canvas.leftProperty);
                
//....
            }


这也就是为什么脚本可以这么写<TextBlock Canvas.left="20">,而TextBlock类却没有一个Canvas.top属性的原因了,而xaml中声明式的指定Canvas.left,是由xaml解析引擎的时候自动完成的。
this.Findname("aTextBlock").SetValue(Canvas.leftProperty,20);

了解了依赖属性的工作方式后,很容易通过这个特点来使用xaml标记用户自定义控件……

就这样了。。。

 

续:

经过继续研究,发现所谓“依赖属性”的作用实在“博大”,它可以使用于本对象以外的"包装类"对其包装,如xaml解析对象通过调用SetValue对UI对象进行初始化;渲染引擎使用GetValue取得它与父元素相依赖的属性值(如在渲染Canvas的子对象时需要子元素中Canvas.top属性的值)

“依赖属性集”既可以放本身需要的属性,也可以放其他元素的所需要的信息集。以“键”和“值”的方式存取。。。。很方便,很强大!

@H_94_404@ 总结

以上是内存溢出为你收集整理的Silverlight学习笔记:“依赖对象”和“依赖属性”全部内容,希望文章能够帮你解决Silverlight学习笔记:“依赖对象”和“依赖属性”所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1058415.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存