<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Shared.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!-- Focus Visual -->
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle Margin="5" StrokeThickness="3"
Stroke="#60000000" StrokeDashArray="4 2"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--...............-->
</ResourceDictionary>
因為這個XAML文件作為資源使用,,所以其根元素是ResourceDictionary,而不再是Window/Application等等,。同時,,資源文件也可以相互的嵌套,比如上面的包含的Shared.xaml文件,。然后定義了一個Style,,注意這里的目標類型為Control.Template,也就是針對所有的控件模板有效,,所以Style添加了一個x:Key屬性,。這樣就阻止Style適用于當前的所有控件。我們必須顯式的引用這個Style,。相關(guān)內(nèi)容,,可以參考我前面的Style文章。
另一個需要說明的是<ControlTemplate>的子元素,,可以是任何的VisualTree,。比如這里的Border,也可以是Grid等等,。好了,,現(xiàn)在定義了一個名為ButtonFocusVisual的模板,下面只需要引用它即可,。
<Style TargetType="Button">
<!--.............-->
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<!--.............-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border" ......./>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DefaultedBorderBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
這是真正影響控件外觀的代碼,。因為在定義Style的時候沒有指定具體的x:Key,所以將影響所有的Button,。如你所見,,在FocusVisualStyle這個屬性(類型是Style)上我們用資源方式引用了前面定義的命名Style:ButtonFocusVisual。接下來是定義Template,,并為其子元素Border定義了一個名稱,。然后就是ControlTemplate的觸發(fā)器。在IsKeyboardFocused屬性滿足條件的情況下,,我們把Border(注意這個Border不是類型,,而是具體的某個對象)的BorderBrush修改為另一個靜態(tài)資源。結(jié)合前面的Post,,理解也就不難了,。
最后,我們還會發(fā)現(xiàn)一個有趣的問題:這個例子雖然是ControlTempalte,,但工程名稱卻是SimpleStyle,從這一點我們也可以看出:Style和Template通常是配合使用才能真正的實現(xiàn)豐富的自定義功能,。