WPF dependency property
WPF dependency property
WPF 提出了 dependency property 這個新型態的 property。它如名稱所說,它依靠許多 provider 來設立它最後的值。以下是它加在 .NET property 上的三個新特性:
Change notification
以往我們要寫滑鼠移到某物件上的動作時,都必需實際寫 code。比如我們要設定 MouseEnter 這個 property,指定到一個 callback function,然後在 callback function 中實現我們想要的動作。
但 dependency property 不用,它完全可以透過 XAML 來實現。像以下的程式碼:
<Button MouseEnter=”Button_MouseEnter” MouseLeave=”Button_MouseLeave”
MinWidth=”75” Margin=”10”>OK</Button>
void Button_MouseEnter(object sender, MouseEventArgs e)
{
Button b = sender as Button;
if (b != null) b.Foreground = Brushes.Blue;
}
void Button_MouseLeave(object sender, MouseEventArgs e)
{
Button b = sender as Button;
if (b != null) b.Foreground = Brushes.Black;
}
就可以簡單的透過 trigger object 來實現:
<Trigger Property=”IsMouseOver” Value=”True”>
<Setter Property=”Foreground” Value=”Blue”/>
</Trigger>
至於 trigger 沒有寫明 mouse leave 時要怎麼做。這邊 WPF 都會自動處理掉。
Property Value Inheritance
而 dependency property value 的值是可以繼承的。假設我們在一個 root window 中設定了某個 dependency property 的值,這個值也會被所有在 logical tree 下的 child 繼承。比如說我們設定 window font size 等於 20,那其下所有像 label, button 等的 control 其 font size 也會被設成 20。然而這個繼承概念並不是套用在所有的 dependency property。一個情況是該 dependency property 在註冊的時候就指定不繼承。另外一個情況是因為 dependency property 的值可以由許多 provider 設立。
Support for Multiple Providers
Dependency property 的值可以被許多 provider 設立,它是有優先順序的:
1. Local value
2. Style triggers
3. Template triggers
4. Style setters
5. Theme style triggers
6. Theme style setters
7. Property value inheritance
8. Default value
1 的優先權最高,8 的優先權最低。所謂 local value 指的就是透過 SetValue 等方式設定的值。而 default value 則是該 property 註冊時提供的值。
Standard Dependency Property Implementation
public class Button : ButtonBase
{
// The dependency property
public static readonly DependencyProperty IsDefaultProperty;
static Button()
{
// Register the property
Button.IsDefaultProperty = DependencyProperty.Register(“IsDefault”,
typeof(bool), typeof(Button),
new FrameworkPropertyMetadata(false,
new PropertyChangedCallback(OnIsDefaultChanged)));
…
}
}
在 WPF 中,dependency property 宣告成 static field。這比傳統 .NET property 宣告成 instance field 比較不佔記憶體。在一個 class 中,無論產生的 class instance 有多少個,static field 永遠指向同一個 storage location;而 instance field 不同,class instance 有多少個,它就有多少個 storage location。
(參考:C# Language spec., 10.4.1 Static and instance fields)
Attached Properties
有些 control 不支援某些 dependency property,但我們又想設定它怎麼辦呢?比如說 StackPanel 並不支援 FontSize 這個 property,但我們想透過直接設定它,來讓所有 StackPanel 的 child 都有相同的 font size。這時候可以使用 TextElement 這個 attached property:
<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>
WPF 提出了 dependency property 這個新型態的 property。它如名稱所說,它依靠許多 provider 來設立它最後的值。以下是它加在 .NET property 上的三個新特性:
Change notification
以往我們要寫滑鼠移到某物件上的動作時,都必需實際寫 code。比如我們要設定 MouseEnter 這個 property,指定到一個 callback function,然後在 callback function 中實現我們想要的動作。
但 dependency property 不用,它完全可以透過 XAML 來實現。像以下的程式碼:
<Button MouseEnter=”Button_MouseEnter” MouseLeave=”Button_MouseLeave”
MinWidth=”75” Margin=”10”>OK</Button>
void Button_MouseEnter(object sender, MouseEventArgs e)
{
Button b = sender as Button;
if (b != null) b.Foreground = Brushes.Blue;
}
void Button_MouseLeave(object sender, MouseEventArgs e)
{
Button b = sender as Button;
if (b != null) b.Foreground = Brushes.Black;
}
就可以簡單的透過 trigger object 來實現:
<Trigger Property=”IsMouseOver” Value=”True”>
<Setter Property=”Foreground” Value=”Blue”/>
</Trigger>
至於 trigger 沒有寫明 mouse leave 時要怎麼做。這邊 WPF 都會自動處理掉。
Property Value Inheritance
而 dependency property value 的值是可以繼承的。假設我們在一個 root window 中設定了某個 dependency property 的值,這個值也會被所有在 logical tree 下的 child 繼承。比如說我們設定 window font size 等於 20,那其下所有像 label, button 等的 control 其 font size 也會被設成 20。然而這個繼承概念並不是套用在所有的 dependency property。一個情況是該 dependency property 在註冊的時候就指定不繼承。另外一個情況是因為 dependency property 的值可以由許多 provider 設立。
Support for Multiple Providers
Dependency property 的值可以被許多 provider 設立,它是有優先順序的:
1. Local value
2. Style triggers
3. Template triggers
4. Style setters
5. Theme style triggers
6. Theme style setters
7. Property value inheritance
8. Default value
1 的優先權最高,8 的優先權最低。所謂 local value 指的就是透過 SetValue 等方式設定的值。而 default value 則是該 property 註冊時提供的值。
Standard Dependency Property Implementation
public class Button : ButtonBase
{
// The dependency property
public static readonly DependencyProperty IsDefaultProperty;
static Button()
{
// Register the property
Button.IsDefaultProperty = DependencyProperty.Register(“IsDefault”,
typeof(bool), typeof(Button),
new FrameworkPropertyMetadata(false,
new PropertyChangedCallback(OnIsDefaultChanged)));
…
}
}
在 WPF 中,dependency property 宣告成 static field。這比傳統 .NET property 宣告成 instance field 比較不佔記憶體。在一個 class 中,無論產生的 class instance 有多少個,static field 永遠指向同一個 storage location;而 instance field 不同,class instance 有多少個,它就有多少個 storage location。
(參考:C# Language spec., 10.4.1 Static and instance fields)
Attached Properties
有些 control 不支援某些 dependency property,但我們又想設定它怎麼辦呢?比如說 StackPanel 並不支援 FontSize 這個 property,但我們想透過直接設定它,來讓所有 StackPanel 的 child 都有相同的 font size。這時候可以使用 TextElement 這個 attached property:
<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>
留言
張貼留言