1. 程式人生 > >WPF:依賴屬性和附加屬性示例

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都繼承了相應的字型與格式,