1、首先必須宣告 Dependency Property
Dependency Property 欄位都是 public、static,並且名稱以「Property」作為結尾。
例如以下宣告:
public static readonly DependencyProperty IsDefaultProperty;
2、在 static 建構子中註冊 Dependency Property
由於 Dependency Property 必須呼叫 static 方法 DependencyProperty.Register() 來建立
而在註冊時,必須在 Register() method 中指定以下內容:
- Dependency Property 的名稱
- Dependency Property 的型態
- 包含 Dependency Property 的 Class 型態
- Metadata (型態為 FrameworkPropertyMetadata,而 Callback Function 宣告於此處)
- 用來檢查 Property 的值是否合法的 function
3、設定 Getter 與 Setter
Dependency Property 宣告了就是用來設定或取值之用的,當然要設定 Getter 與 Setter 囉!
但比較特別的是,Dependency Property 值的設定或取得,是透過 System.Windows.DependencyObject 中的 SetValue() 與 GetValue() 來處理的。
而比較需要注意的是,若是有任何的程式邏輯或是檢查要加入,請記得加到 Callback Function 中,別加在 Getter 與 Setter 中,因為那只是用來取值或設定值之用。
(所有 WPF 內建的屬性封裝都遵守此規則,因此別亂寫囉!)
使用 Dependency Property 的優點 & 所提供的功能
1、節省記憶體
想像一下,Button 類別有將近 100 個欄位值,每個 Label 也將近有 90 個欄位值,若是畫面中有一堆 Button 與 Label 所產生的物件,記憶體的耗用量豈不是很可觀?
沒錯,這就是 Dependency Property 所要解決的問題,透過 static 的方式先產生 Dependency Property,在將 Button 與 Label 物件的屬性「依附上去」。
當每個 Button 或是 Label 都依附到同一個 Dependency Property,如此一來,記憶體的用量就會大大地減少囉!
2、變更告知 (Change Notification)
WPF 可以根據 Dependency Property 的 Metadata 自動觸法許多動作,例如:重新整理元素、更新畫面配置、重新整理資料繫結...等等。
範例:以下程式實作滑鼠移到按鈕上後,更改文字顏色(Button 的 IsMouseOver 屬性被更改,自動觸發更改文字顏色)
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="About WPF Unleashed" SizeToContent="WidthAndHeight" Background="OrangeRed" FontSize="30" FontStyle="Italic">
Chapter 1
Chapter 2
You have seccessfully registered this product.
3、屬性值繼承 (Property Value Inheritance)
元素樹中,父節點的控制項屬性會向下套用到子系的控制項屬性。
但也是有些例外的情況,原因可能會有兩種:
- 在 DependencyProperty.Register() 裡,透過 FrameworkPropertyMetadata.Options.Inherits 設定為不繼承父系控制項的屬性值。
- 子系控制項覆寫了繼承來的屬性值。
4、支援多重提供者
WPF 中有許多屬性提供者可用不同的方式設定 Dependency Property,而屬性值的決定過程會經過五個步驟:
- 判斷基底值
這個部分會由多種屬性提供者來提供值,優先順序為:
Local Value -> Style Trigger -> Template Trigger -> Style Setter -> Theme Style Trigger -> Theme Style Setters -> Property Value Inheritance -> Default Value - 驗算
此部份進行屬性值的驗算,為運算式。 - 套用動畫
若有一個以上的動畫正在執行,它們可以改變目前的屬性值,甚至完全置換掉。 - 轉換
若有註冊 CoerceValueCallback 委派,則屬性值會被傳遞到此 function 進行轉換,以取得更新後的值。
(例如 ProgressBar 就是利用 callback function 來保持屬性值不會超過最大或最小值) - 驗證
最後還會進行屬性值的驗證,決定該值是否合法。(若有設定 ValidateValueCallback 委派)
5、附加屬性 (Attached Property)
附加屬性(attached property)是種特殊的 Dependency Property,可以附加到任何物件上,以下直接用範例說明:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="About WPF Unleashed" Background="OrangeRed">
Chapter 1
Chapter 2
You have seccessfully registered this product
從程式碼可以看出,透過附加屬性的使用,StackPanel 中的控制項就不用一一加上 FontSize & FontStyle 兩個屬性了。
參考資料
Anita 的.NET 世界: 什麼是Dependency Property
design studio: Dependency Property
WPF Tutorial | Introduction to DependencyProperties
Are you looking to earn cash from your websites with popup ads?
回覆刪除If so, did you try using PopCash?