WPF中的依賴項屬性(轉)
出處:https://www.cnblogs.com/axzxs2001/archive/2010/04/25/1719857.html
隨著WPF的推廣,不得不重新拾起WPF來,因為這塊的產品越來越多。
只能跟著MSDN來學了,所以想是在這裡記錄下學習的過程和對知識的理解。
先從最基本的吧,依賴項屬性是WPF中不同的地方,先了解一下它吧。
“依賴項屬性的用途在於提供一種方法來基於其他輸入的值計算屬性值”,這是官方的一句話,理解起來有點費勁。屬性本身其實很簡單,就是用來封裝了欄位的,本質上是兩個訪問器,來達到對欄位值的讀與寫,以及從業務角度保護欄位的業務有效性(因為大部分欄位都有一定的業務含義,即有業務含義,就有一定範圍,比如工資,是個小數的型別,但工資不可能是負數,所以在封裝工資欄位時,要在set訪問器中作限制)。但依賴項屬性不只這麼簡單了,屬性的值不是簡單的封裝欄位,而是根據其他的輸入值來決定本屬性的值。為什麼要這樣做?因為在WPF體系中,只有定義屬性為依賴項屬性,這個屬性才支援樣式設定,資料繫結,繼承,動畫和預設值
怎麼樣才能使一個屬性成為依賴項屬性呢?
首先,屬性所在的類要直接或間接繼承DependencyObject。這個類生成的物件表示一個具有依賴項屬性的物件,這些物件,都能享用WPF的屬性系統(屬性系統主要是計算屬性的值,並提供有關值已更改的系統通知)方面的服務。
這個類有兩個比較重要的方法,GetValue(返回當前物件依賴項屬性的當前有效值)和SetValue(設定依賴項屬性的本地值)。
其實,屬性對應的欄位必需是公有,靜態,只讀的,型別為DependencyProperty。即public static readonly DependencyProperty 欄位名,同時欄位的命名也有規範,屬性名+Property,欄位在定義時,通過DependencyProperty.Register來實註冊屬性(只有註冊了,才能使用WPF屬性系統的服務)。
Register方法有三種過載,如下:
名稱 |
說明 |
Register(String, Type, Type) |
使用指定的屬性名稱、屬性型別和屬性所在物件的型別。 |
Register(String, Type, Type, PropertyMetadata) |
使用指定的屬性名稱、屬性型別、屬性所在物件的型別和屬性元資料註冊依賴項屬性。 |
Register(String, Type, Type, PropertyMetadata, ValidateValueCallback) |
使用指定的屬性名稱、屬性型別、屬性所在物件的型別、屬性元資料和屬性的值驗證回撥來註冊依賴項屬性。 |
在Register中,各個引數解釋如下:
String:依賴屬性的名字(不加Property,即欄位的名字);
Type:屬性的型別;
Type:屬性所屬物件的型別;
PropertyMetadata:依賴項物件的屬性元資料,是一個PropertyMetadata型別,可能賦初始值。PropertyMetadata有一個object的建構函式;
ValidateValueCallback:表示用作回撥的方法,這個型別是一個委託,用於驗證依賴項屬性的值的有效性,因為是委託,故它的構造引數為一個方法名。
最後,來構造依賴屬性,與普通的屬性有所區別:
Public 屬性型別 屬性名
{
Get
{
return (屬性型別)this.GetValue(欄位名);
}
Set
{
this.SetValue(欄位名, value);
}
}
其中的GetValue和SetValue都是呼叫父類DependencyObject的方法。
完整的程式碼如下:
程式碼 1 class MyClass : DependencyObject
2 {
3 public static readonly DependencyProperty MyfieldProperty = DependencyProperty.Register("Myfield", typeof(int), typeof(MyClass), new PropertyMetadata(0), new ValidateValueCallback(new MyClass().MyValidateMethod));
4 public int Myfield
5 {
6 get { return (int)GetValue(MyfieldProperty); }
7 set { SetValue(MyfieldProperty, value); }
8 }
9 public bool MyValidateMethod(object value)
10 {
11 return true;//這裡實現驗證
12 }
13 }
14
WPF中,大部分物件的屬性都是依賴項屬性,用Button來舉例,Button類的繼承關係如下:
可以很明顯的看到,Button是間接繼承DependencyObject的。再看看他的屬性:
拿ISDefault屬性來看,它有一個IsDefalutProperty的欄位,型別為DependencyProperty,IsDefault的程式碼如下:
完全與我們定義的依賴項屬性一樣。因為只有這樣,這些屬性才能使用WPF屬性系統服務。