WPF - Attached Property 深入探討
此篇延續上一篇Dependency Property內容,上一篇談到最後,提到了一個初次進入WPF或是Silverlight時,會覺得很奇怪的地方,例如說設定DockPanel的上下左右對齊,通常我會覺得說,至少會這樣寫 ( 小弟膚淺的認知. )。
<DockPanel xxx=left> <Button/> </DockPanel>
但在WPF裡面,卻是這樣寫。
<Button DockPanel.Dock="Top">
程式碼的話,會這樣寫。
DockPanel.setDock(btn,Dock.Top);
沒錯,並沒有看錯,呼叫一個靜態類別DockPanel,然後使用靜態方法setDock(),裡面第一個參數是要設定位置的控制項,第二個參數則是利用Dock的列舉型別來設定上下左右。
老實說,我第一次看到,會覺得很詭異,為什麼會用這麼詭異的方式進行設定呢?也完全顛覆了我之前的認知( 所以說,我很膚淺嘛~~ )。
Attached Property
中文翻譯叫做附加屬性;既然Attached Property會放在Dependency Property後面講,大家應該就可以猜的到了,會用那麼奇怪的寫法,其實這個的原始技術還是在Dependency Property。
首先我們先來看,實際的DockPanel原始碼,其實內容和之前講的Dependency Property類似,比較不同的是,這裡的DockProperty是使用DependencyProperty.RegisterAttached來進行註冊的,此外,get和set裡面,都有傳入UIElement進來,簡單的說,就是使用傳進來的UIElement來呼叫SetValue和GetValue,而非是呼叫DockPanel的SetValue和GetValue。
public class DockPanel : Panel { public static readonly DependencyProperty DockProperty; public static void SetDock(UIElement el,Dock dck) { el.SetValue(DockProperty,dck); } public static Dock GetDock(UIElement el) { return (Dock) el.GetValue(DockProperty); } }
那這樣代表甚麼,記不記得前面Dependency Property有提到,利用SetValue會將資料存到某個Collection裡面,所以簡單的說,我們在DockPanel設定了靜態方法SetDock和GetDock,但實際上,上下左右的設定,會存放到,由SetValue第一個參數傳入進去的UIElement元件裡面去。而這種感覺,就像是我們在DockPanel設定了DockProperty這個屬性,但實際上,此屬性附加到了真實會用到的控制項上面,所以才會有Attached Property之稱。
Attached Property的一些特點
前面有提到,既然不是呼叫DockPanel裡面的SetValue和GetValue,所以我們可以發現到,其實時要實踐attached property的類別是不需要延生自DependencyObject的!,當然要實際SetValue和GetValue的類別還是要延生自DependencyObject。
其次,其實前面寫到這樣的設定上下左右。
DockPanel.SetDock(btn,Dock.Top)
懂得原理後,其實我們也可以這樣寫,道理是相通的。
btn.SetValue(DockPanel.DocProperty,Dock.Top)
所以這兩種基本上是一樣的,也因此,Attached Property算是Dependency Property的一種延伸型態,
為什麼使用Attached Property
要提到這個,又要講古了,以前的Win Forms程式可能會這樣寫。
btn.Dock = Dock.Top
而使用這種方法,最大的問題就是,如果btn沒有在Dock下面,那這個屬性就等同於沒有用,所以後來WPF才實作出這種有彈性的天才作法 ( 老實說,真的很厲害… ),所以以後要寫WPF,要設定上下左右,就不會覺得奇怪啦..
參考資料