基礎知識:
- DependencyObject ?& DependencyProperty 類位于System.Windows命名空間,程序集:WindowsBase.dll;
- DependencyObject類通過其各子類開啟WPF屬性系統服務;
- 屬性系統的主要功能是:將計算屬性值和提供值改變的系統通知;
- DependencyProperty類是另一個在屬性系統中起重要作用的類;
- 依賴屬性是一種能夠注冊到WPF屬性系統的屬性,可通過Styling、Data Binding和Inheritance進行使用;
- DependencyProperty類可將依賴屬性注冊到屬性系統中,并提供每個依賴屬性的認證和信息;
- 使用依賴屬性的類必須是DependencyObject類的子類,或者說必須是依賴對象才能作為依賴屬性的宿主;
- DependencyProperty不能被直接實例化,因為它沒有public的構造函數;
- DependencyProperty只能使用靜態DependencyProperty.Register()方法創建其實例;
- WPF確保DependencyProperty對象被創建后不能被改變(readonly);
- WPF允許對象在被創建的時候并不創建包含用于存儲數據的空間,可只保留在需要用到數據時能夠獲得默認值,且借用其他對象的數據或實時分配空間的能力來實現。這種對象即依賴對象,這種實時獲取數據的能力則由依賴屬性實現。
- DependencyProperty必須以DependencyObject為宿主,并借助其SetValue和GetValue方法進行數值的寫入與讀取;
- 依賴屬性必須在靜態構造函數中進行設置;
- DependencyObject有 ClearValue 的方法,用于刪除屬性的本地值;
- 依賴屬性的共享,比如,TextBlock.FontFamily屬性和Control.FontFamily屬性指向同一個靜態的依賴項屬性TextElement.FOntFamily;使用 DependencyProperty.AddOwner() 方法重用該屬性;
- 附加屬性也是依賴屬性的一種,定義附加屬性需要使用 RegisterAttached ()方法;
- ValidateValueCallback回調函數可接受或拒絕新值,用于捕獲明顯的違反屬性約束的錯誤;而CoerceValueCallback回調函數可將新值改為更能被接受的值,有點類似Validate的效果;
順序: CoerceValueCallback → ValidateValueCallback → 如果前兩個階段都成功,觸發PropertyChangedCallback方法。 ▲ ▲ ▲ ▲
常用類及其一些方法:
◎ ?DependencyObject類中的SetValue()和GetValue()方法:
//
//
摘要:
//
返回 System.Windows.DependencyObject 的此實例上的依賴項屬性的當前有效值。
//
//
參數:
//
dp:
//
要為其檢索值的屬性的 System.Windows.DependencyProperty 標識符。
//
//
返回結果:
//
返回當前的有效值。
//
//
異常:
//
System.InvalidOperationException:
//
指定的 dp 或其值無效,或者指定的 dp 不存在。
public
object
GetValue(DependencyProperty dp);
//
//
摘要:
//
設置依賴項屬性的本地值,該依賴項屬性由其標識符指定。
//
//
參數:
//
dp:
//
要設置的依賴項屬性的標識符。
//
//
value:
//
新的本地值。
//
//
異常:
//
System.InvalidOperationException:
//
嘗試修改只讀依賴項屬性,或嘗試修改密封 System.Windows.DependencyObject 上的屬性。
//
//
System.ArgumentException:
//
value 的類型不是為 dp 屬性注冊時使用的正確類型。
public
void
SetValue(DependencyProperty dp,
object
value);
//
//
摘要:
//
設置只讀依賴項屬性的本地值,該依賴項屬性由其 System.Windows.DependencyPropertyKey 標識符指定。
//
//
參數:
//
key:
//
要設置的屬性的 System.Windows.DependencyPropertyKey 標識符。
//
//
value:
//
新的本地值。
public
void
SetValue(DependencyPropertyKey key,
object
value);
? ?? ◎ DependencyProperty類的Register方法原型:
//
//
摘要:
//
使用指定的屬性名稱、屬性類型和所有者類型注冊依賴項屬性。
//
//
參數:
//
name:
//
要注冊的依賴項對象的名稱。 在所有者類型的注冊命名空間內,名稱必須是唯一的。
//
//
propertyType:
//
屬性的類型。
//
//
ownerType:
//
正注冊依賴項對象的所有者類型。
//
//
返回結果:
//
一個依賴項對象標識符,應使用它在您的類中設置 public static readonly 字段的值。 然后,在以后使用該標識符引用依賴項對象,用于某些操作,例如以編程方式設置其值,或者獲取元數據。
public
static
DependencyProperty Register(
string
name, Type propertyType, Type ownerType);
//
//
摘要:
//
使用指定的屬性名稱、屬性類型、所有者類型和屬性元數據注冊依賴項屬性。
//
//
參數:
//
name:
//
要注冊的依賴項對象的名稱。
//
//
propertyType:
//
屬性的類型。
//
//
ownerType:
//
正注冊依賴項對象的所有者類型。
//
//
typeMetadata:
//
依賴項對象的屬性元數據。
//
//
返回結果:
//
一個依賴項對象標識符,應使用它在您的類中設置 public static readonly 字段的值。 然后,在以后使用該標識符引用依賴項對象,用于某些操作,例如以編程方式設置其值,或者獲取元數據。
public
static
DependencyProperty Register(
string
name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata);
//
//
摘要:
//
使用指定的屬性名稱、屬性類型、所有者類型、屬性元數據和屬性的值驗證回調來注冊依賴項屬性。
//
//
參數:
//
name:
//
要注冊的依賴項對象的名稱。
//
//
propertyType:
//
屬性的類型。
//
//
ownerType:
//
正注冊依賴項對象的所有者類型。
//
//
typeMetadata:
//
依賴項對象的屬性元數據。
//
//
validateValueCallback:
//
對回調的引用,除了典型的類型驗證之外,該引用還應執行依賴項對象值的任何自定義驗證。
//
//
返回結果:
//
一個依賴項對象標識符,應使用它在您的類中設置 public static readonly 字段的值。 然后,在以后使用該標識符引用依賴項對象,用于某些操作,例如以編程方式設置其值,或者獲取元數據。
public
static
DependencyProperty Register(
string
name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback);
◎? ValidateValueCallback的定義:
namespace
System.Windows
{
//
摘要:
//
表示用作回調的方法,用于驗證依賴項屬性的值是否有效。
//
//
參數:
//
value:
//
要驗證的值。
//
//
返回結果:
//
如果該值通過了驗證,則為 true;如果提交的值無效,則為 false。
public
delegate
bool
ValidateValueCallback(
object
value);
}
?
◎? PropertyMetaData類:
//
摘要:
//
定義依賴項對象在應用于特定類型(包括該屬性向其注冊的條件)時行為的某些方面。
public
PropertyMetadata();
//
//
摘要:
//
使用此元數據將應用于的依賴項對象的指定默認值,初始化 System.Windows.PropertyMetadata 類的新實例。
//
//
參數:
//
defaultValue:
//
要為依賴項對象指定的默認值,通常作為某種特定類型的值提供。
//
//
異常:
//
System.ArgumentException:
//
defaultValue 不能設置為值 System.Windows.DependencyProperty.UnsetValue;請參見“備注”。
public
PropertyMetadata(
object
defaultValue);
//
//
摘要:
//
用指定的 System.Windows.PropertyChangedCallback 實現引用初始化 System.Windows.PropertyMetadata
//
類的新實例。
//
//
參數:
//
propertyChangedCallback:
//
對處理程序實現的引用,每當屬性的有效值更改時,屬性系統都將調用該處理程序實現。
public
PropertyMetadata(PropertyChangedCallback propertyChangedCallback);
//
//
摘要:
//
用指定的默認值和 System.Windows.PropertyChangedCallback 實現引用初始化 System.Windows.PropertyMetadata
//
類的新實例。
//
//
參數:
//
defaultValue:
//
依賴項對象的默認值,通常作為某種特定類型的值提供。
//
//
propertyChangedCallback:
//
對處理程序實現的引用,每當屬性的有效值更改時,屬性系統都將調用該處理程序實現。
//
//
異常:
//
System.ArgumentException:
//
defaultValue 不能設置為值 System.Windows.DependencyProperty.UnsetValue;請參見“備注”。
public
PropertyMetadata(
object
defaultValue, PropertyChangedCallback propertyChangedCallback);
//
//
摘要:
//
用指定的默認值和回調初始化 System.Windows.PropertyMetadata 類的新實例。
//
//
參數:
//
defaultValue:
//
依賴項對象的默認值,通常作為某種特定類型的值提供。
//
//
propertyChangedCallback:
//
對處理程序實現的引用,每當屬性的有效值更改時,屬性系統都將調用該處理程序實現。
//
//
coerceValueCallback:
//
對處理程序實現的引用,每當屬性系統對該屬性調用 System.Windows.DependencyObject.CoerceValue(System.Windows.DependencyProperty)
//
時都將調用此處理程序實現。
//
//
異常:
//
System.ArgumentException:
//
defaultValue 不能設置為值 System.Windows.DependencyProperty.UnsetValue;請參見“備注”。
public
PropertyMetadata(
object
defaultValue, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback);
◎? CoerceValueCallback的定義:
/ /
摘要:
//
為只要重新計算依賴項屬性值或專門請求強制轉換時就調用的方法提供一個模板。
//
//
參數:
//
d:
//
該屬性所在的對象。 在調用該回調時,屬性系統將會傳遞該值。
//
//
baseValue:
//
該屬性在嘗試執行任何強制轉換之前的新值。
//
//
返回結果:
//
強制轉換后的值(采用適當的類型)。
public
delegate
object
CoerceValueCallback(DependencyObject d,
object
baseValue);
?
?
★對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.
"
);
}
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

