WPF Dependency相關特點介紹
WPF開發工具的作用在實際編程中是非常有用的。我們可以通過平時的實踐去積累各種經驗來達到熟練運用的程度。本篇,我們再繼續看一種特殊的WPF Dependency屬性:Attached屬性。Attached屬性可以非常高效地Attach到其他的對象中。 #t#
我們仍然用前面的一個簡單XAML代碼為例:
- < Window> < StackPanel>
- < Label>LabelText< /Lable>
- < /StackPanel> < /Window>
現在,如果需要對StackPanel及其子元素設置字體大小,應該如何做呢?在Window元素中,它有一個屬性FontSize,可以直接設置。但是,StackPanel自己本身并沒有FontSize這樣的屬性。這就該Attached屬性出場了。這里我們需要用定義在TextElement元素中的Attached屬性FontSize來設置StackPanel的字體。
- < Window>
- < StackPanel TextElement.
FontSize=”30”>- < Label>LabelText< /Lable>
- < /StackPanel> < /Window>
這樣,StackPanel的子元素就能通過屬性值繼承得到新的FontSize屬性。對于這樣的XAML代碼,XAML編譯器或者解析器看到這種語法時,就要求TextElement(有時也稱為Attached屬性提供者)有相應的靜態方法SetFontSize來設置對應的屬性值。因此,上面的Attached屬性設置代碼,可以如下用C#實現:
- StackPanel panel =
new StackPanel();- TextElement.SetFont
Size(panel, 30);
從這里的代碼可以看出,Attached屬性并不神秘。只是調用方法把元素和不相關的屬性關聯起來。而SetFontSize實現也比較簡單。它只是調用了WPF Dependency屬性訪問函數所調用的DependencyObject.SetValue方法。注意調用的對象是傳入的DependencyObject,而不是當前的實例:
- public static void SetFontSize
(DependencyObject element,
double value)- {
- element.SetValue(TextElement.
FontSizeProperty, value);- }
同樣地,Attached屬性也定義了對應的GetXXX函數。它調用的DependencyObject.GetValue方法:
- public static double
GetFontSize(Dependency
Object element)- {
- return (double)element.
GetValue(TextElement.
FontSizeProperty);- }
與普通的WPF Dependency屬性一樣,這些GetXXX和SetXXX方法除了實現對GetValue和SetValue的調用,不能做任何其他額外的工作。
其實,在WPF應用中,Attached屬性更多的用來控制UI的布局。除了前面的StackPanel,還有Grid等等。
補充說明:上面的代碼還有一個問題需要說明。我們設置StackPanel的字體屬性時用的是TextElement元素。為什么不用其他的元素Control、Button呢?
這個問題的關鍵之處在于Dependency屬性的注冊方法。我曾在WPF Dependency屬性[1]做過簡單的說明。我們看看Element的FontSizeProperty屬性的注冊代碼:
- TextElement.FontSizeProperty =
DependencyProperty.RegisterAttached
( “FontSize”, typeof(double),
typeof(TextElement), new Framewor
kPropertyMetadata( SystemFonts.
MessageFontSize, FrameworkProperty
MetadataOptions.Inherits |
FrameworkPropertyMetadataOptions.
AffectsRender | FrameworkProperty
MetadataOptions.AffectsMeasure),
new ValidateValueCallback
(TextElement.IsValidFontSize));
這里與我們前面的IsDefault屬性類似,只是RisterAttached方法優化了Attached屬性需要的屬性元數據的處理過程。
另一方面,Control的FontSize屬性是在TextElement元素已經注冊的屬性之上調用AddOwner方法,獲取一個完全相同的實例引用:
- Control.FontSizeProperty =
TextElement.FontSizeProperty.
AddOwner( typeof(Control),
new FrameworkPropertyMetadata
(SystemFonts.MessageFontSize,
FrameworkPropertyMetadata
Options.Inherits));
所以,在實現Attached屬性時我們使用的是TextElement,而不是Control等等。
我們為大家介紹的WPF Dependency就到這里了。