基礎(chǔ)知識(shí):
- DependencyObject ?& DependencyProperty 類位于System.Windows命名空間,程序集:WindowsBase.dll;
- DependencyObject類通過其各子類開啟WPF屬性系統(tǒng)服務(wù);
- 屬性系統(tǒng)的主要功能是:將計(jì)算屬性值和提供值改變的系統(tǒng)通知;
- DependencyProperty類是另一個(gè)在屬性系統(tǒng)中起重要作用的類;
- 依賴屬性是一種能夠注冊(cè)到WPF屬性系統(tǒng)的屬性,可通過Styling、Data Binding和Inheritance進(jìn)行使用;
- DependencyProperty類可將依賴屬性注冊(cè)到屬性系統(tǒng)中,并提供每個(gè)依賴屬性的認(rèn)證和信息;
- 使用依賴屬性的類必須是DependencyObject類的子類,或者說必須是依賴對(duì)象才能作為依賴屬性的宿主;
- DependencyProperty不能被直接實(shí)例化,因?yàn)樗鼪]有public的構(gòu)造函數(shù);
- DependencyProperty只能使用靜態(tài)DependencyProperty.Register()方法創(chuàng)建其實(shí)例;
- WPF確保DependencyProperty對(duì)象被創(chuàng)建后不能被改變(readonly);
- WPF允許對(duì)象在被創(chuàng)建的時(shí)候并不創(chuàng)建包含用于存儲(chǔ)數(shù)據(jù)的空間,可只保留在需要用到數(shù)據(jù)時(shí)能夠獲得默認(rèn)值,且借用其他對(duì)象的數(shù)據(jù)或?qū)崟r(shí)分配空間的能力來實(shí)現(xiàn)。這種對(duì)象即依賴對(duì)象,這種實(shí)時(shí)獲取數(shù)據(jù)的能力則由依賴屬性實(shí)現(xiàn)。
- DependencyProperty必須以DependencyObject為宿主,并借助其SetValue和GetValue方法進(jìn)行數(shù)值的寫入與讀取;
- 依賴屬性必須在靜態(tài)構(gòu)造函數(shù)中進(jìn)行設(shè)置;
- DependencyObject有 ClearValue 的方法,用于刪除屬性的本地值;
- 依賴屬性的共享,比如,TextBlock.FontFamily屬性和Control.FontFamily屬性指向同一個(gè)靜態(tài)的依賴項(xiàng)屬性TextElement.FOntFamily;使用 DependencyProperty.AddOwner() 方法重用該屬性;
- 附加屬性也是依賴屬性的一種,定義附加屬性需要使用 RegisterAttached ()方法;
- ValidateValueCallback回調(diào)函數(shù)可接受或拒絕新值,用于捕獲明顯的違反屬性約束的錯(cuò)誤;而CoerceValueCallback回調(diào)函數(shù)可將新值改為更能被接受的值,有點(diǎn)類似Validate的效果;
順序: CoerceValueCallback → ValidateValueCallback → 如果前兩個(gè)階段都成功,觸發(fā)PropertyChangedCallback方法。 ▲ ▲ ▲ ▲
常用類及其一些方法:
◎ ?DependencyObject類中的SetValue()和GetValue()方法:

// // 摘要: // 返回 System.Windows.DependencyObject 的此實(shí)例上的依賴項(xiàng)屬性的當(dāng)前有效值。 // // 參數(shù): // dp: // 要為其檢索值的屬性的 System.Windows.DependencyProperty 標(biāo)識(shí)符。 // // 返回結(jié)果: // 返回當(dāng)前的有效值。 // // 異常: // System.InvalidOperationException: // 指定的 dp 或其值無效,或者指定的 dp 不存在。 public object GetValue(DependencyProperty dp); // // 摘要: // 設(shè)置依賴項(xiàng)屬性的本地值,該依賴項(xiàng)屬性由其標(biāo)識(shí)符指定。 // // 參數(shù): // dp: // 要設(shè)置的依賴項(xiàng)屬性的標(biāo)識(shí)符。 // // value: // 新的本地值。 // // 異常: // System.InvalidOperationException: // 嘗試修改只讀依賴項(xiàng)屬性,或嘗試修改密封 System.Windows.DependencyObject 上的屬性。 // // System.ArgumentException: // value 的類型不是為 dp 屬性注冊(cè)時(shí)使用的正確類型。 public void SetValue(DependencyProperty dp, object value); // // 摘要: // 設(shè)置只讀依賴項(xiàng)屬性的本地值,該依賴項(xiàng)屬性由其 System.Windows.DependencyPropertyKey 標(biāo)識(shí)符指定。 // // 參數(shù): // key: // 要設(shè)置的屬性的 System.Windows.DependencyPropertyKey 標(biāo)識(shí)符。 // // value: // 新的本地值。 public void SetValue(DependencyPropertyKey key, object value);
? ?? ◎ DependencyProperty類的Register方法原型:

// // 摘要: // 使用指定的屬性名稱、屬性類型和所有者類型注冊(cè)依賴項(xiàng)屬性。 // // 參數(shù): // name: // 要注冊(cè)的依賴項(xiàng)對(duì)象的名稱。 在所有者類型的注冊(cè)命名空間內(nèi),名稱必須是唯一的。 // // propertyType: // 屬性的類型。 // // ownerType: // 正注冊(cè)依賴項(xiàng)對(duì)象的所有者類型。 // // 返回結(jié)果: // 一個(gè)依賴項(xiàng)對(duì)象標(biāo)識(shí)符,應(yīng)使用它在您的類中設(shè)置 public static readonly 字段的值。 然后,在以后使用該標(biāo)識(shí)符引用依賴項(xiàng)對(duì)象,用于某些操作,例如以編程方式設(shè)置其值,或者獲取元數(shù)據(jù)。 public static DependencyProperty Register( string name, Type propertyType, Type ownerType); // // 摘要: // 使用指定的屬性名稱、屬性類型、所有者類型和屬性元數(shù)據(jù)注冊(cè)依賴項(xiàng)屬性。 // // 參數(shù): // name: // 要注冊(cè)的依賴項(xiàng)對(duì)象的名稱。 // // propertyType: // 屬性的類型。 // // ownerType: // 正注冊(cè)依賴項(xiàng)對(duì)象的所有者類型。 // // typeMetadata: // 依賴項(xiàng)對(duì)象的屬性元數(shù)據(jù)。 // // 返回結(jié)果: // 一個(gè)依賴項(xiàng)對(duì)象標(biāo)識(shí)符,應(yīng)使用它在您的類中設(shè)置 public static readonly 字段的值。 然后,在以后使用該標(biāo)識(shí)符引用依賴項(xiàng)對(duì)象,用于某些操作,例如以編程方式設(shè)置其值,或者獲取元數(shù)據(jù)。 public static DependencyProperty Register( string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata); // // 摘要: // 使用指定的屬性名稱、屬性類型、所有者類型、屬性元數(shù)據(jù)和屬性的值驗(yàn)證回調(diào)來注冊(cè)依賴項(xiàng)屬性。 // // 參數(shù): // name: // 要注冊(cè)的依賴項(xiàng)對(duì)象的名稱。 // // propertyType: // 屬性的類型。 // // ownerType: // 正注冊(cè)依賴項(xiàng)對(duì)象的所有者類型。 // // typeMetadata: // 依賴項(xiàng)對(duì)象的屬性元數(shù)據(jù)。 // // validateValueCallback: // 對(duì)回調(diào)的引用,除了典型的類型驗(yàn)證之外,該引用還應(yīng)執(zhí)行依賴項(xiàng)對(duì)象值的任何自定義驗(yàn)證。 // // 返回結(jié)果: // 一個(gè)依賴項(xiàng)對(duì)象標(biāo)識(shí)符,應(yīng)使用它在您的類中設(shè)置 public static readonly 字段的值。 然后,在以后使用該標(biāo)識(shí)符引用依賴項(xiàng)對(duì)象,用于某些操作,例如以編程方式設(shè)置其值,或者獲取元數(shù)據(jù)。 public static DependencyProperty Register( string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback);
◎? ValidateValueCallback的定義:
namespace System.Windows { // 摘要: // 表示用作回調(diào)的方法,用于驗(yàn)證依賴項(xiàng)屬性的值是否有效。 // // 參數(shù): // value: // 要驗(yàn)證的值。 // // 返回結(jié)果: // 如果該值通過了驗(yàn)證,則為 true;如果提交的值無效,則為 false。 public delegate bool ValidateValueCallback( object value); }
?
◎? PropertyMetaData類:

// 摘要: // 定義依賴項(xiàng)對(duì)象在應(yīng)用于特定類型(包括該屬性向其注冊(cè)的條件)時(shí)行為的某些方面。 public PropertyMetadata(); // // 摘要: // 使用此元數(shù)據(jù)將應(yīng)用于的依賴項(xiàng)對(duì)象的指定默認(rèn)值,初始化 System.Windows.PropertyMetadata 類的新實(shí)例。 // // 參數(shù): // defaultValue: // 要為依賴項(xiàng)對(duì)象指定的默認(rèn)值,通常作為某種特定類型的值提供。 // // 異常: // System.ArgumentException: // defaultValue 不能設(shè)置為值 System.Windows.DependencyProperty.UnsetValue;請(qǐng)參見“備注”。 public PropertyMetadata( object defaultValue); // // 摘要: // 用指定的 System.Windows.PropertyChangedCallback 實(shí)現(xiàn)引用初始化 System.Windows.PropertyMetadata // 類的新實(shí)例。 // // 參數(shù): // propertyChangedCallback: // 對(duì)處理程序?qū)崿F(xiàn)的引用,每當(dāng)屬性的有效值更改時(shí),屬性系統(tǒng)都將調(diào)用該處理程序?qū)崿F(xiàn)。 public PropertyMetadata(PropertyChangedCallback propertyChangedCallback); // // 摘要: // 用指定的默認(rèn)值和 System.Windows.PropertyChangedCallback 實(shí)現(xiàn)引用初始化 System.Windows.PropertyMetadata // 類的新實(shí)例。 // // 參數(shù): // defaultValue: // 依賴項(xiàng)對(duì)象的默認(rèn)值,通常作為某種特定類型的值提供。 // // propertyChangedCallback: // 對(duì)處理程序?qū)崿F(xiàn)的引用,每當(dāng)屬性的有效值更改時(shí),屬性系統(tǒng)都將調(diào)用該處理程序?qū)崿F(xiàn)。 // // 異常: // System.ArgumentException: // defaultValue 不能設(shè)置為值 System.Windows.DependencyProperty.UnsetValue;請(qǐng)參見“備注”。 public PropertyMetadata( object defaultValue, PropertyChangedCallback propertyChangedCallback); // // 摘要: // 用指定的默認(rèn)值和回調(diào)初始化 System.Windows.PropertyMetadata 類的新實(shí)例。 // // 參數(shù): // defaultValue: // 依賴項(xiàng)對(duì)象的默認(rèn)值,通常作為某種特定類型的值提供。 // // propertyChangedCallback: // 對(duì)處理程序?qū)崿F(xiàn)的引用,每當(dāng)屬性的有效值更改時(shí),屬性系統(tǒng)都將調(diào)用該處理程序?qū)崿F(xiàn)。 // // coerceValueCallback: // 對(duì)處理程序?qū)崿F(xiàn)的引用,每當(dāng)屬性系統(tǒng)對(duì)該屬性調(diào)用 System.Windows.DependencyObject.CoerceValue(System.Windows.DependencyProperty) // 時(shí)都將調(diào)用此處理程序?qū)崿F(xiàn)。 // // 異常: // System.ArgumentException: // defaultValue 不能設(shè)置為值 System.Windows.DependencyProperty.UnsetValue;請(qǐng)參見“備注”。 public PropertyMetadata( object defaultValue, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback);
◎? CoerceValueCallback的定義:
/ / 摘要: // 為只要重新計(jì)算依賴項(xiàng)屬性值或?qū)iT請(qǐng)求強(qiáng)制轉(zhuǎn)換時(shí)就調(diào)用的方法提供一個(gè)模板。 // // 參數(shù): // d: // 該屬性所在的對(duì)象。 在調(diào)用該回調(diào)時(shí),屬性系統(tǒng)將會(huì)傳遞該值。 // // baseValue: // 該屬性在嘗試執(zhí)行任何強(qiáng)制轉(zhuǎn)換之前的新值。 // // 返回結(jié)果: // 強(qiáng)制轉(zhuǎn)換后的值(采用適當(dāng)?shù)念愋停? public delegate object CoerceValueCallback(DependencyObject d, object baseValue);
?
?
★對(duì)DependencyObject和DependencyProperty的模擬,見源博客鏈接 http://www.cnblogs.com/eagle1986/archive/2012/08/17/2643332.html :★

public class MyDenpendencyObject { private Dictionary< string , object > properties = new Dictionary< string , object > (); protected object GetValue(MyDenpendencyProperty property) { if (property.OwnerType == this .GetType()) { return this .properties[property.Name]; } else { MyDenpendencyObject parent = this .GetParentElement(property.OwnerType); return parent.GetValue(property); } } protected void SetValue(MyDenpendencyProperty property, object value) { this .properties[property.Name] = value; } private MyDenpendencyObject GetParentElement(Type type) { return null ; } } public class MyDenpendencyProperty { private MyDenpendencyProperty( string name, Type valueType, Type ownerType, object defaultValue) { this .Name = Name; this .ValueType = valueType; this .OwnerType = ownerType; this .DefaultValue = defaultValue; } public static MyDenpendencyProperty Register( string name, Type valueType, Type ownerType, object defaultValue) { return new MyDenpendencyProperty(name, valueType, ownerType, defaultValue); } public string Name { get ; private set ; } public Type ValueType { get ; private set ; } public Type OwnerType { get ; private set ; } public object DefaultValue { get ; private set ; } } public class MyParentElement : MyDenpendencyObject { public string Text { get { return ( string )GetValue(TextProperty); } set { SetValue(TextProperty, value); } } public static readonly MyDenpendencyProperty TextProperty = MyDenpendencyProperty.Register( " Text " , typeof ( string ), typeof (MyParentElement), " This is a super class. " ); } public class MyChildElement : MyDenpendencyObject { public string Text { get { return ( string )GetValue(TextProperty); } set { SetValue(TextProperty, value); } } public static readonly MyDenpendencyProperty TextProperty = MyDenpendencyProperty.Register( " Text " , typeof ( string ), typeof (MyParentElement), " This is a sub-class. " ); }
?
WPF基礎(chǔ)學(xué)習(xí)筆記整理 (五) DependencyObject & DependencyProperty
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
