1. 樣式
1.1 樣式的基本使用
樣式類似於html中的樣式,用來提取出來共用的一些外觀屬性,一般其它地方共享。style是一組Setter的集合。
一個簡單的例子:
<StackPanel Orientation="Horizontal" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <StackPanel.Resources> <Style x:Key="buttonStyle"> <Setter Property="Button.FontSize" Value="22"/> <Setter Property="TextBox.Background" Value="Black"/> <Setter Property="Button.Background" Value="Purple"/> <Setter Property="TextBox.Foreground" Value="White"/> <Setter Property="Button.Height" Value="50"/> </Style> </StackPanel.Resources> <Button Style="{StaticResource buttonStyle}">1</Button> <Button Style="{StaticResource buttonStyle}">2</Button> <Button Style="{StaticResource buttonStyle}">3</Button> <TextBox Style="{StaticResource buttonStyle}"></TextBox> </StackPanel>
使用樣式的特點:
* 當Style被應用到一個沒有默寫屬性的元素上的時候,它只會對存在的屬性進行設置,不存在的則會被忽略。
* Sytle還有一個不確定性,比如上面定義的TextBox.Background為Black不起作用,應該是被下面的Button.Background覆蓋了。這些產生的原因還不確定,為了避免這種情況,建議為不同的類型創建不同的Style
* 限制Style的使用范圍。可以設置TargetType屬性來限制Style只能應用於特定的控件。
* 隱式Style,也叫類型化樣式, 就是沒有指定key的Style, 那么該Style會被默認的應用到所有的目標類型元素。類型化樣式的有效范圍是由Style資源的位置決定的。
1.2 觸發器
三種類型的觸發器:
- 屬性觸發器, 當依賴屬性的值改變時調用
- 數據觸發器,當普通.net屬性值改變時調用
- 事件觸發器,當路由事件被觸發時調用
我們可以使用屬性觸發器和數據觸發器來設置不同的Style。
一個屬性觸發器的例子:
<StackPanel Orientation="Horizontal" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="200"> <StackPanel.Resources> <Style TargetType="{x:Type TextBox}"> <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="disabled"> <Setter Property="IsEnabled" Value="False"/> </DataTrigger> </Style.Triggers> <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Text}"/> <Setter Property="Width" Value="200"/> </Style> </StackPanel.Resources> <TextBox Margin="3"/> </StackPanel>
2. 模板
目前來看,你只能通過修改控件的屬性來修改外觀,但是實際上可以使用控件模板來隨意的改造控件。
它的原理是模板允許你用空想出來的任何東西完全替換一個元素的可視樹,但其它的功能不會受到影響。
一個使用控件模板的例子,一個漂亮的圓形Button
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid.Resources> <ControlTemplate x:Key="buttonTemplate"> <Grid> <Ellipse Width="100" Height="100"> <Ellipse.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Offset="0" Color="Blue"/> <GradientStop Offset="1" Color="Red"/> </LinearGradientBrush> </Ellipse.Fill> </Ellipse> <Ellipse Width="80" Height="80"> <Ellipse.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Offset="0" Color="White"/> <GradientStop Offset="1" Color="Transparent"/> </LinearGradientBrush> </Ellipse.Fill> </Ellipse> </Grid> </ControlTemplate> </Grid.Resources> <Button Template="{StaticResource buttonTemplate}">OK</Button> </Grid>
在控件模板中,也可以使用Trigger和限制目標類型。
3. 皮膚
WPF並沒有獨特的叫做皮膚的概念,也沒有一個正式的換膚概念,那是因為WPF不需要這種東西。
可以用WPF寫一個動態換膚的應用程序或組件,這可以通過WPF的動態資源機制加上Style和模板來實現。
4. 主題
皮膚是跟着應用程序走的,但主題通常涉及操作系統的視覺特性,它會反映在所有程序的用戶界面的元素上。
對於默認的控件模板而言,於操作系統的主題保持一致很重要。
4.1 使用系統顏色、字體和參數
當Windows主題改變時,由SystemColors, SystemFonts和SystemParameters類提供的成員會自動更新。我們可以使用它們,放到我們的樣式和模板中,這是讓它們融入到用戶主題的一個簡單方式。
4.2 創建自己的主題樣式和模板
第一步把指定的資源放入不同的資源字典的XAML文件中(一個主題一個文件), 然后經編譯放入程序集中。 你可以把資源字典放入主題目錄(必須在項目的根目錄),從而把每個資源字典指派為一個主題字典,並把它們命名為ThemeName.ThemeColor.xaml。當你的應用程序啟動或者主題改變時,WPF會自動加載和應用主題字典。