在前一個(gè)Post中,曾提到將要重點(diǎn)研究Dependency屬性的三個(gè)方面:變化通知;屬性值的繼承;支持多個(gè)提供對象。下面,我將分別就這三個(gè)內容進(jìn)行簡(jiǎn)單地說(shuō)明。
【變化通知】
在任何時(shí)候,只要Dependency屬性的值發(fā)生了變化,WPF可以自動(dòng)地根據屬性的元數據觸發(fā)不同的行為。前面提到過(guò):Dependency屬性最大的特點(diǎn)就是內建的變化通知功能。這種內建變化通知所提供的最值得注意的就是屬性觸發(fā)器(Property Trigger),就是它使用我們不需要編寫(xiě)任何的程序代碼就能在屬性變化使執行自定義行為。請看下面XAML編碼的一個(gè)屬性觸發(fā)器例子:
<Trigger Property=”IsMouseOver” Value=”True”>
<Setter Property=”Foreground” Value=”Blue”/>
</Trigger>
它的功能就是在屬性值IsMouseOver變?yōu)?/span>True的時(shí),將屬性Foreground的值設置為Blue。而且,它會(huì )在IsMouseOver變?yōu)?/span>False時(shí)自動(dòng)將Foreground的值設置為原來(lái)的值。就是這樣簡(jiǎn)單的三行代碼完成了我們曾經(jīng)需要多個(gè)函數、變量才能實(shí)現的功能。
使用屬性觸發(fā)器時(shí)需要注意:觸發(fā)器默認適用于每個(gè)類(lèi)對象。 而且,在WPF 3.0中由于人為的限制,Property Trigger將不能應用在單獨的元素。只能應用在某個(gè)Style對象之中。因此,如果想在某個(gè)單獨對象上實(shí)現Property Trigger。必須用如下的XAML進(jìn)行封裝:
<Button MinWidth=”75” Margin=”10”>
<Button.Style>
<Style TargetType=”{x:Type Button}”>
<Style.Triggers>
<Trigger Property=”IsMouseOver” Value=”True”>
<Setter Property=”Foreground” Value=”Blue”/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
OK
</Button>
【屬性值繼承】
屬性值繼承是指在設置邏輯樹(shù)某個(gè)結點(diǎn)元素的屬性后,它的所有之結點(diǎn)都繼承這個(gè)屬性值(當然,前提是子元素必須支持這個(gè)屬性)。我們仍然利用閑話(huà)WPF之八中的一個(gè)例子進(jìn)行說(shuō)明:
<Window FontSize=”30”>
<StackPanel>
<Label>LabelText</Lable>
</StackPanel>
</Window>
我們修改了Window是FontSize屬性為30。通過(guò)實(shí)際觀(guān)察將發(fā)現它的子元素Label的FontSize也變?yōu)榱?/span>30。注意這里的StackPanel是一個(gè)容器元素,它本身并不支持FontSize屬性。
現在我們給上面的Window添加一個(gè)狀態(tài)欄。XAML代碼如下:
<Window ......>
<StackPanel>
<Label>LabelText</Lable>
<StatusBar>This is a Statusbar</StatusBar>
</StackPanel>
</Window>
這時(shí)你會(huì )發(fā)現:雖然StatusBar支持這個(gè)FontSize這個(gè)屬性,它也是Window的子元素,但是它的字體大小卻沒(méi)有變化。為什么呢?因為并不是所有的元素都支持屬性值繼承。還存在如下兩種例外的情況:
1、部分Dependency屬性在用Register注冊時(shí)可以指定Inherits為不可繼承。
2、如果有其他更高優(yōu)先級方法設置了其他的值。(關(guān)于優(yōu)先級的介紹且看下面分解。)
部分控件如StatusBar、Menu和Tooptip內部設置它們的字體屬性值以匹配當前系統的設置。這樣用戶(hù)通過(guò)控制面板可以修改它們的外觀(guān)。這種方法存在一個(gè)問(wèn)題:StatusBar等截獲了從父元素繼承來(lái)的屬性,并且不影響其子元素。比如,如果我們在StatusBar中添加了一個(gè)Button。這個(gè)Button的字體屬性會(huì )因為StatusBar的截斷沒(méi)沒(méi)有改變,將保留其默認值。
附加說(shuō)明:屬性值繼承的最初設計只適用于元素Tree,現在已經(jīng)進(jìn)行多個(gè)方面的擴展。比如,值可以傳遞下級看起來(lái)像Children,但在邏輯或者視覺(jué)Tree中并不是Children的某些元素。這些偽裝的子元素可以是觸發(fā)器、屬性的值,只要它是從Freezable繼承的對象。對于這些內容沒(méi)有很好的文檔說(shuō)明。我們只需要能使用就行不必過(guò)多關(guān)心。聯(lián)系客服