WPF:依賴屬性和附加屬性示例
public class Button : ButtonBase { // 依賴屬性 public static readonly DependencyProperty IsDefaultProperty; static Button() { // 註冊屬性 Button.IsDefaultProperty = DependencyProperty.Register("IsDefault", typeof(bool), typeof(Button), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsDefaultChanged))); …… } // .net屬性包裝器(可選) public bool IsDefalut { get { return (bool)GetValue(Button.IsDefaultProperty); } set { SetValue(Button.IsDefaultProperty, value); } } // 屬性改變的回撥(可選) private static void OnIsDefaultChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { …… } }
IsDefaultProperty靜態成員是真正的依賴屬性,型別為System.Windows.DependencyProperty。按規則,所有的DependencyProperty成員都必須是public、static,並且有一個Property作為字尾。依賴屬性通常是通過呼叫DependencyProperty.Register靜態方法建立的,這樣的方法需要一個名稱(IsDefault)、一個屬性型別(bool)以及擁有這個屬性的類(Button類)。。通過不同的Register方法過載,你可以傳入metadata(元資料)來告訴WPF如何處理該屬性、如何處理屬性值改變的回撥、如何處理強制值轉,以及如何驗證值。Button會在它的靜態建構函式中呼叫Register的過載,給依賴屬性一個預設值false,併為變更通知新增一個委託。
最後,那個叫作IsDefault的傳統.NET屬性會呼叫繼承自System.Windows.Dependency-Object的GetValue和SetValue方法來實現自己的訪問器,System.Windows.DependencyObject是底層基類,這是擁有依賴屬性的類必須繼承的。GetValue返回最後一次由SetValue設定的值,如果SetValue從未被呼叫過,那麼就是該屬性註冊時的預設值。IsDefault .NET屬性(有時叫作此上下文中的屬性包裝器)並不是必需的,Button的使用者可能會直接呼叫GetValue/ SetValue方法,因為它們是公開的。但是.NET屬性會讓以程式設計方式讀寫屬性變得更加自然,它還允許通過XAML設定屬性。
附加屬性:
附加屬效能夠啟用一些我們所盼望的屬性值(被新增的元素並沒有該屬性值)繼承特性,是依賴屬性的一種特殊形式,可以被有效地新增到任何物件中。
<StackPanel TextElement.FontSize="30" TextElement.FontStyle="Italic"
Orientation="Horizontal" HorizontalAlignment="Center">
<Button MinWidth="75" Margin="10">Help</Button>
<Button MinWidth="75" Margin="10">OK</Button>
</StackPanel>
上例中,因為StackPanel自己沒有任何與字型相關的屬性。相反,你必須使用FontSize和FontStyle附加屬性,這是在一個叫作TextElement的類中定義的。這樣,在StackPanel中的兩個子元素button都繼承了相應的字型與格式,