WPF依賴屬性詳解
WPF 依賴屬性 英文譯為 Dependency Properties,是WPF引入的一種新類型的屬性,在WPF中有著極為廣泛的應用,在WPF中對於WPF Dependency Properties 的使用貫穿樣式的使用,數據綁定,動畫等等,在剛剛接觸Dependency Properties的時候可能覺得有些奇怪,但是,當你了解他要解決的問題的時候,你可能就不覺得奇怪了。Dependency Properties第一個要解決的問題就是控件的屬性共享問題,由於大部分的WPF控件都有多達上百個屬性,如果每個屬性都是使用實例屬性,那對於一個有著成百上千控件的應用來說後果是不堪設想的,Dependency Properties 使用靜態共享的方式解決了這個問題,下面的代碼說明了這個solution.
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))); … } // A .NET property wrapper (optional) public bool IsDefault { get { return ( bool)GetValue( Button.IsDefaultProperty); } set { SetValue( Button.IsDefaultProperty, value); } } // A property changed callback (optional) private static void OnIsDefaultChanged( DependencyObject o, DependencyPropertyChangedEventArgs e) { … } … }
另外相對於普通的WPF屬性,Dependency Properties 還有如下的優勢
Property value inheritance -- 屬性繼承
Change notification -- 改變通知
Support for multiple providers -- 支持多個提供者
下面讓我們首選來看看屬性繼承的效果和代碼,從這兩張圖上讀者可以看出,窗體上所有的字體都變大了,從30變成了50,但是這個改變並不是通過設置每個控件的屬性得到的,我只需要設置窗體的一個屬性,這個窗體的子控件就會適應這一改變,並且使用相同的設置,這就是,屬性繼承,區別於傳統的OO繼承,這種方式的繼承主要是控件樹上元素的繼承,相對應的代碼如下所示。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Title="WPF Example" SizeToContent="WidthAndHeight" FontSize="50" FontStyle="Italic" Background="Blue"> <StackPanel> <Label FontWeight="Bold" FontSize="20" Foreground="White"> Hi There! </Label> <Label>2015 Solidmango</Label> <ListBox> <ListBoxItem>Item1</ListBoxItem> <ListBoxItem>Item2</ListBoxItem> </ListBox> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <Button MinWidth="75" Margin="10">Help</Button> <Button MinWidth="75" Margin="10">OK</Button> </StackPanel> <StatusBar>Solidmango</StatusBar> </StackPanel> </Window>
對於屬性的改變通知主要說的是通常我們使用普通屬性時只有通過事件響應函數,或者回調函數才能解決的問題,使用 Dependency Properties 只需要及其簡單的配置就可以解決,相對於普通屬性,方便性不言而喻。下面我們對比一下這兩種方式的代碼。
使用普通屬性
<Button MouseEnter=” Button_MouseEnter” MouseLeave=” Button_MouseLeave” MinWidth=” 75” Margin=” 10” >Help</Button> <Button MouseEnter=” Button_MouseEnter” MouseLeave=” Button_MouseLeave” MinWidth=” 75” Margin=” 10” >OK</Button> // Change the foreground to blue when the mouse enters the button void Button_MouseEnter( object sender, MouseEventArgs e) { Button b = sender as Button; if (b != null) b.Foreground = Brushes.Blue; } // Restore the foreground to black when the mouse exits the button void Button_MouseLeave( object sender, MouseEventArgs e) { Button b = sender as Button; if (b != null) b.Foreground = Brushes.Black; }
使用依賴屬性
<Trigger Property=” IsMouseOver” Value=” True” > <Setter Property=” Foreground” Value=” Blue” /> </Trigger>
對於多提供者的支持也是 Dependency Properties 的特色之一,具體的提供者優先級如下:
Determine Base Value
1.Local value
2. Parent template trigger
3. Parent template
4. Style triggers
5. Template triggers
6. Style setters
7. Theme style triggers
8. Theme style setters
9. Property value inheritance
10. Default value
Evaluate (if an Expression)
Apply Animations
Coerce
Validate
WPF依賴屬性詳解