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

学习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属性的值)

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值