偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Silverlight基礎(chǔ)屬性:依賴與附加

開發(fā) 后端 前端
依賴屬性(Dependency Property)和附加屬性(Attached Property)這兩個算是Silverlight中非常基礎(chǔ)的知識,特別是CLR屬性,這個在DotNet編程中隨處可見。

作為微軟進(jìn)軍RIA領(lǐng)域的武器,Silverlight正在得到微軟的大力推廣,其***版本也在不久前的MIX10大會上發(fā)布,新版本不僅增多了50多項(xiàng)功能,同時也向我們呈現(xiàn)了各種開發(fā)工具包。

在Silverlight中,依賴屬性(Dependency Property)和附加屬性(Attached Property)這兩個算是很基礎(chǔ)的知識,下面我們著重分析這兩個屬性。

CLR屬性與依賴屬性

CLR屬性我們非常熟悉了,在DotNet編程中隨處可見。最簡單最常見的屬性訪問器就是直接操縱類的私有成員,如下:

  1. public class Person{      
  2. private String _name;      
  3. public string Name      
  4. {          
  5. get { return _name; }         
  6. set { _name = value; }      
  7. }} 

C#3.0對這種常見的寫法提供了“自動屬性”這一特性,方便了偶等這些懶惰的碼農(nóng)。

  1. public class Person{      
  2. public string Name { get; set; }  

這兩種寫法是等價的,都是需要設(shè)立一個實(shí)例級的私有變量作為屬性訪問器的持久存儲。這對于我們非UI應(yīng)用來說沒什么。因?yàn)?**,我們一般不會創(chuàng)建太多類實(shí)例;第二,一個類的屬性通常不會很多,加幾個私有變量不會增加系統(tǒng)負(fù)擔(dān)。但是這兩個理由對于UI應(yīng)用程序來說恰恰不成立。

在很多UI應(yīng)用中,我們經(jīng)常會創(chuàng)建很多類實(shí)例,成千上萬個實(shí)例在UI系統(tǒng)中是很普遍的事情。同時,UI類通常會包含大量的屬性供設(shè)計(jì)人員使用,例如背景顏色,前景顏色,字體,邊距等等,這些屬性在絕大多數(shù)情況下會保持默認(rèn)值,如果為每個實(shí)例都建立這么多的私有變量來存儲UI屬性的值,勢必會造成極大的浪費(fèi),對系統(tǒng)負(fù)擔(dān)的開銷也是不小。鑒于以上提到的問題,設(shè)計(jì)一個高效的屬性存儲系統(tǒng)對于UI應(yīng)用程序的開發(fā)是非常重要的。因此Silverlight引入了“依賴屬性(DependencyProperty)”。

采用鍵值對替代成員變量作為屬性內(nèi)部存儲

傳統(tǒng)CLR屬性,一個屬性對應(yīng)一個私有變量,UI元素的屬性那么多,創(chuàng)建過多的私有變量不是一件簡單的事情,況且大多數(shù)屬性只會用到默認(rèn)值。因此Silverlight使用鍵值對的形式來存放那些用戶顯式設(shè)置的屬性(稱為Local Value本地值),沒有設(shè)置的屬性就不存。那屬性的默認(rèn)值存放在哪?既然各個實(shí)例的默認(rèn)值都一樣(不然也不叫默認(rèn)值了),那么直接存放到靜態(tài)成員變量上就行了。這也就大大提高了存儲的效率。

注冊依賴屬性

既然依賴屬性采用鍵值對這樣的哈希結(jié)構(gòu)進(jìn)行存儲,那么要獲取不同屬性的值,我們就必須使用不同的哈希鍵,否則就會讀取到其他屬性的值了。因此,當(dāng)我們在向Silverlight屬性系統(tǒng)注冊依賴屬性的時候,Silverlight會返回一個唯一的屬性標(biāo)識對象,類型為DependencyProperty。我們以后就通過這個唯一標(biāo)識對象去訪問依賴屬性的值。

由于這個唯一標(biāo)識符是所有類實(shí)例都公用并且不會被修改的,因此我們通常將其保存到一個static readonly的成員變量中。DependencyProperty類提供了兩個方法,一個是Register方法,用于注冊依賴屬性;另外一個是RegisterAttached,用于注冊附加屬性。

  1. public static DependencyProperty Register(string name,Type propertyType,Type ownerType,PropertyMetadata typeMetadata) 
  2.  

Register方法的簽名由幾部分組成,Name參數(shù)指明了依賴屬性使用的名稱,這個名字很重要,在定義控件Style和Template的時候,Setter的Property屬性填入的值就是注冊依賴屬性時使用的名稱;propertyType指明了依賴屬性實(shí)際的類型,ownerType指明了是哪個類注冊了此依賴屬性,***typeMetadata存放了一些依賴屬性的元信息,包括依賴屬性使用的默認(rèn)值,還有屬性值發(fā)生變更時的通知函數(shù)。 #p#

屬性的存取

和CLR屬性不同,依賴屬性不是直接對私有變量的操縱,而是通過GetValue和SetValue的方法來操作屬性值的。下面的代碼演示了為Ball控件設(shè)置一個Center的依賴屬性,并且在程序中讀取和修改此屬性的過程:

  1. public class Ball : Control{      
  2. public static readonly DependencyProperty CenterProperty =          
  3. DependencyProperty.Register("Center", typeof(Point), typeof(Ball), null);  
  4. }  
  5. public class BallApp{    public void RollBall(Ball ball)      
  6. {          
  7. Point curCenter = (Point)ball.GetValue(Ball.CenterProperty);  
  8. curCenter.X++;        // 注意對值類型對象操作完畢之后一定要調(diào)用SetValue修改才能生效          
  9. ball.SetValue(Ball.CenterProperty, curCenter);      
  10. }} 

由于上述對依賴屬性的操作經(jīng)常需要涉及到類型的轉(zhuǎn)換,比較麻煩,而傳統(tǒng)CLR屬性用起來和直接操縱普通變量一樣方便,因此通常在設(shè)計(jì)依賴屬性的時候,都會使用CLR屬性將其包裝起來,我們稱之為增強(qiáng)型的CLR屬性。

  1. public class Ball : Control{   
  2. public static readonly DependencyProperty CenterProperty =          
  3. DependencyProperty.Register("Center", typeof(Point), typeof(Ball), null);          
  4. public Point Center      
  5. { get { return (Point)GetValue(CenterProperty); }          
  6. set { SetValue(CenterProperty, value); }    }} 

按照約定,依賴屬性的名稱通常是相應(yīng)CLR屬性名稱后面加上個“Property”字符串。事實(shí)上,使用CLR包裝依賴屬性并不只是為了方便,很多依賴于CLR屬性作為基礎(chǔ)的工具或者子系統(tǒng)并不能直接訪問依賴屬性,而只能通過CLR屬性去間接訪問依賴屬性。

例如上面的例子中,假設(shè)我們并沒有設(shè)置一個Center的CLR屬性,那么以下的Xaml將會編譯失敗,因?yàn)閄aml解析器無法知道Ball類有一個Center的依賴屬性(在Style中設(shè)置Center屬性值就可以編譯成功,因?yàn)镾tyle是動態(tài)查找屬性的)。<Ball Center="2" />依賴屬性的尋值邏輯和值變更通知,上面提到的只是依賴屬性相比CLR屬性在存儲效率的不同,實(shí)際上,依賴屬性還有其他實(shí)用的特性。

尋值邏輯

CLR屬性在獲取值的時候是直接讀取成員變量值返回的,而依賴屬性在使用的時候是通過GetValue函數(shù)的調(diào)用來獲取屬性的值。實(shí)際上,GetValue內(nèi)部做的事情可不止是簡單的讀取字典里頭存放的值。他還有尋值邏輯。如下圖所示:

當(dāng)你調(diào)用GetValue去讀取一個依賴屬性的值的時候,Silverlight的屬性系統(tǒng)會首先從動畫系統(tǒng)中查找當(dāng)前是否有作用在此依賴屬性上的動畫,如果有,則返回此動畫值。從這里也可以看出,依賴屬性是Silverlight實(shí)現(xiàn)動畫機(jī)制的基礎(chǔ)。注意,如果動畫已經(jīng)停止了,并且沒有設(shè)置FillBehavior=HoldEnd的話,那么Silverlight就不會返回此動畫值。

如果讀不到動畫值,那么Silverlight就會嘗試讀取本地值。本地值有幾種類型,一種是用戶通過代碼或者Xaml直接設(shè)定的值。一種是通過資源綁定得到的值,***一種是通過數(shù)據(jù)綁定得到的值。這些都被視為本地值。

  1. <StackPanel x:Name="LayoutRoot">      
  2. <StackPanel.Resources>          
  3. <System:String x:Key="TextBlockResource">資源數(shù)據(jù)綁定文本  
  4. </System:String>    </StackPanel.Resources>      
  5. <TextBlock Text="{Binding Source={StaticResource TextBlockResource}}" />      
  6. <TextBlock x:Name="DataBindingElement" Text="{Binding ElementName}" /> 
  7. </StackPanel> 

如果還是讀取不到,那么就繼續(xù)嘗試讀取控件模板和樣式中設(shè)置的值。如果所有這些值都讀取失敗,那么Silverlight屬性系統(tǒng)就會返回該依賴屬性的默認(rèn)值。當(dāng)我們注冊依賴屬性的時候,可以傳入一個PropertyMetaData對象,這個對象包含了此依賴屬性的默認(rèn)值和值變更通知回調(diào)函數(shù)。如果注冊的時候沒有傳入默認(rèn)值,則對于引用類型的依賴屬性,返回null,對于字符串,返回String.Empty,對于值類型,則返回一個以默認(rèn)值初始化的實(shí)例。這里需要對集合類型特別注意,由于通過PropertyMetaData傳入的默認(rèn)值是所有類實(shí)例共享的,因此,一定要在類構(gòu)造函數(shù)中顯式傳入集合的實(shí)例。

  1. public class GameRoom : Control{     
  2.  public List<Ball> Balls      
  3. {          
  4. get { return (List<Ball>)GetValue(BallsProperty);   
  5. }          
  6. set { SetValue(BallsProperty, value); }      
  7. }     
  8.  public static readonly DependencyProperty BallsProperty =          
  9. DependencyProperty.Register("Balls", typeof(List<Ball>), typeof(GameRoom), null);   
  10.    public GameRoom()    {          
  11. Balls = new List<Ball>();    }} 

可能正是因?yàn)镾ilverlight的依賴屬性在獲取值的時候需要從多個地方去讀取值,而不是像CLR屬性一樣,直接從成員變量中讀取值,所以才被稱之為“依賴”屬性吧。#p#

值變更通知

屬性值的變更通知我們并不陌生。我們在DotNet中實(shí)現(xiàn)的時候,一般是讓類實(shí)現(xiàn)INotifyPropertyChanged接口。在UI系統(tǒng)中,值變更通知是經(jīng)常需要用到的。數(shù)據(jù)源一旦變更,所有相應(yīng)的UI元素的值都要相應(yīng)的做出調(diào)整。Silverlight的依賴屬性對此有內(nèi)置的支持。只要你在綁定時使用依賴屬性,那么當(dāng)依賴屬性值發(fā)生變更的時候,所有綁定的地方的值都會同步更新。而且,依賴屬性也提供了一個值變更通知函數(shù)(在注冊依賴屬性時通過PropertyMetaData傳入),你可以自定義一個函數(shù)來控制值變更時需要執(zhí)行的操作。

  1. public class Ball : Control{      
  2. public static readonly DependencyProperty   
  3.  
  4. CenterProperty=DependencyProperty.Register("Center", typeof(Point), typeof(Ball), new PropertyMetadata(OnCenterChanged));  
  5.     public Point Center    {          
  6. get { return (Point)GetValue(CenterProperty);   
  7. }         
  8.  set { SetValue(CenterProperty, value); }      
  9. }      
  10. private static void OnCenterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)      
  11. {         
  12.  Ball ball = d as Ball;        // 獲取新的球心         
  13.  Point newCenter = (Point)e.NewValue;     // Silverlight的附加屬性(Attached Property)  

全局的依賴屬性

剛才提到的依賴屬性和CLR屬性一樣都是服務(wù)于某一個類的。只不過將屬性改造得存儲上更有效率,使用上更加強(qiáng)大。在Silverlight中還有一種特殊的依賴屬性,這種依賴屬性并不只是服務(wù)于某個特定的類,而是服務(wù)于全局,這就是附加屬性。從名字上也可以看出來,附加屬性是在某個類里面注冊,然后可以被其他類所使用。什么情況下需要使用附加屬性呢?舉Canvas類的ZIndex屬性作為例子。容器類在疊加子控件的時候,需要考慮哪個控件放置在最上面,那個放在下面。

那么容器類怎么知道子控件的疊放順序呢?最不動腦子的設(shè)計(jì)就是為所有的控件都添加一個ZIndex的屬性,屬性的值代表疊放的順序。但這樣的后果就是,如果我這個控件不參與布局,那多這個屬性就會顯得很浪費(fèi)。所以比較理想的設(shè)計(jì)是,需要用到這個屬性的時候就有這個屬性,不需要的時候就沒有這個屬性的負(fù)擔(dān)。附加屬性的出現(xiàn)就是為了解決這樣的問題。一旦控件需要某個屬性的時候,我們可以把這個屬性附加到這個控件類上。注冊附加屬性和依賴屬性差不多,只不過函數(shù)名為RegisterAttached。這個就不多說了。

什么時候應(yīng)該用到依賴屬性

既然依賴屬性那么高效,而且那么強(qiáng)大,那么我們是不是應(yīng)該保持使用依賴屬性的習(xí)慣呢?事實(shí)上,任何好處都是有代價的。Silverlight的依賴屬性在訪問效率上并不如直接訪問成員變量那么高效。因此,對于那些比較簡單而訪問頻率又非常高的屬性,建議還是使用傳統(tǒng)的CLR屬性去實(shí)現(xiàn)。

【編輯推薦】

  1. 簡單Silverlight應(yīng)用程序五步走 
  2. Silverlight WCF服務(wù)正確組建方法淺談
  3. Silverlight調(diào)用WCF出現(xiàn)異常解決方案
  4. 細(xì)數(shù)2009年Silverlight十大流行應(yīng)用
  5. 為你揭開Silverlight代碼安全性秘密

 

責(zé)任編輯:王曉東 來源: 博客園
相關(guān)推薦

2010-01-04 18:26:11

Silverlight

2009-12-23 11:24:42

WCF附加屬性

2009-12-29 10:22:34

WPF附加屬性

2009-12-30 13:59:58

Silverlight

2015-09-17 13:42:26

2009-08-03 13:53:30

C#調(diào)用Excel

2009-08-06 09:37:09

Silverlight

2009-03-19 09:01:53

Silverlight微軟Flash

2010-09-01 14:41:35

paddingline-heightCSS

2009-08-21 14:07:05

Flex與Silver

2010-03-17 09:22:06

FlashSilverlight

2016-03-30 11:54:20

2009-11-17 10:47:14

Silverlight

2009-05-13 15:46:30

FlashSilverlight大比拼

2010-02-22 17:34:39

WCF依賴屬性

2023-09-15 11:49:33

wpf依賴屬性

2023-04-28 09:05:20

魔方基礎(chǔ)流程

2010-01-04 16:06:34

Silverlight

2009-10-27 10:28:33

Silverlight

2011-12-28 10:49:44

Silverlight
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號