走進WPF之樣式


WPF通過樣式,不僅可以方便的設置控件元素的展示方式,給用戶呈現多樣化的體驗,還簡化配置,避免重復設置元素的屬性,以達到節約成本,提高工作效率的目的。本文以一個簡單的小例子,簡述如果設置WPF的樣式,僅供學習分享使用,如有不足之處,還請指正。

什么是樣式?

樣式(Style)是組織和重用格式化選項的重要工具。不是使用重復的標記填充XAML,以便設置外邊距、內邊距、顏色以及字體等細節,而是創建一系列封裝所有這些細節的樣式,然后再需要之處通過屬性來應用樣式。
樣式是可應用於元素的屬性值集合。使用資源的最常見原因之一就是樣式。

基礎樣式

1. 通過TargetType設置樣式

通過控件類型,統一設置樣式【如:字體,大小,邊距等】,以便於形成統一的風格。如下所示:

示例源碼

通過設置樣式的TargetType="Button",則可以使所有的按鈕應用同一個樣式,統一風格。如下所示:

 1 <Window x:Class="WpfApp1.SevenWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WpfApp1"
 7         mc:Ignorable="d"
 8         Title="基礎樣式示例" Height="250" Width="400">
 9     <Window.Resources>
10         <Style  TargetType="Button"  >
11             <Setter Property="Button.Margin" Value="2,5,2,5"></Setter>
12             <Setter Property="Control.FontFamily" Value="SimSun-ExtB"></Setter>
13             <Setter Property="Control.FontSize" Value="18"></Setter>
14         </Style>
15     </Window.Resources>
16     <StackPanel>
17         <Button x:Name="button1" Content="第一個按鈕"></Button>
18         <Button x:Name="button2" Content="第二個按鈕" ></Button>
19         <Button x:Name="button3" Content="第三個按鈕"></Button>
20         <Button x:Name="button4" Content="第四個按鈕" ></Button>
21     </StackPanel>
22 </Window>

2. 通過Key設置樣式

如果需要對每一個控件元素,都設置不同的樣式,則可以通過不同的Key加以區分,如下所示:

示例源碼

分別設置不同的樣式,每一個樣式都有一個唯一的Key,然后分別綁定到各個元素的Style屬性上,如下所示:

 1 <Window x:Class="WpfApp1.SevenWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WpfApp1"
 7         mc:Ignorable="d"
 8         Title="基礎樣式示例" Height="250" Width="400">
 9     <Window.Resources>
10         <Style TargetType="Button" >
11             <Setter Property="Button.Margin" Value="2,5,2,5"></Setter>
12             <Setter Property="Control.FontFamily" Value="SimSun-ExtB"></Setter>
13             <Setter Property="Control.FontSize" Value="16"></Setter>
14         </Style>
15         <Style x:Key="first">
16             <Setter Property="Control.Foreground" Value="Red"></Setter>
17             <Setter Property="Control.Background" Value="Gray"></Setter>
18         </Style>
19         <Style x:Key="second">
20             <Setter Property="ItemsControl.Foreground" Value="Gold"></Setter>
21             <Setter Property="ItemsControl.Background" Value="DarkCyan"></Setter>
22         </Style>
23         <Style x:Key="third">
24             <Setter Property="ItemsControl.Foreground" Value="White"></Setter>
25             <Setter Property="ItemsControl.Background" Value="DarkRed"></Setter>
26         </Style>
27         <Style x:Key="four">
28             <Setter Property="ItemsControl.Foreground" Value="Blue"></Setter>
29             <Setter Property="ItemsControl.Background" Value="LightCoral"></Setter>
30         </Style>
31     </Window.Resources>
32     <StackPanel>
33         <Button x:Name="button1" Content="第一個按鈕" Style="{StaticResource first}"></Button>
34         <Button x:Name="button2" Content="第二個按鈕" Style="{StaticResource second}"></Button>
35         <Button x:Name="button3" Content="第三個按鈕" Style="{StaticResource third}"></Button>
36         <Button x:Name="button4" Content="第四個按鈕" Style="{StaticResource four}"></Button>
37     </StackPanel>
38 </Window>

3. 樣式繼承

通過仔細觀察發現,在設置了單獨樣式以后,統一的樣式失去了作用,說明每一個元素控件,只能綁定一個樣式,那怎么辦才能讓統一樣式起作用呢?答案就是面向對象思想中的繼承。

在WPF中,通過設置BasedOn來繼承父樣式,如下所示:

 示例源碼

在每一個樣式通過BasedOn屬性繼承父樣式,如下所示:

 1 <Window x:Class="WpfApp1.SevenWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WpfApp1"
 7         mc:Ignorable="d"
 8         Title="基礎樣式示例" Height="250" Width="400">
 9     <Window.Resources>
10         <Style x:Key="base" >
11             <Setter Property="Control.Margin" Value="2,5,2,5"></Setter>
12             <Setter Property="Control.FontFamily" Value="SimSun-ExtB"></Setter>
13             <Setter Property="Control.FontSize" Value="18"></Setter>
14         </Style>
15         <Style x:Key="first" BasedOn="{StaticResource base}">
16             <Setter Property="Control.Foreground" Value="Red"></Setter>
17             <Setter Property="Control.Background" Value="Gray"></Setter>
18         </Style>
19         <Style x:Key="second" BasedOn="{StaticResource base}">
20             <Setter Property="ItemsControl.Foreground" Value="Gold"></Setter>
21             <Setter Property="ItemsControl.Background" Value="DarkCyan"></Setter>
22         </Style>
23         <Style x:Key="third" BasedOn="{StaticResource base}">
24             <Setter Property="ItemsControl.Foreground" Value="White"></Setter>
25             <Setter Property="ItemsControl.Background" Value="DarkRed"></Setter>
26         </Style>
27         <Style x:Key="four" BasedOn="{StaticResource base}">
28             <Setter Property="ItemsControl.Foreground" Value="Blue"></Setter>
29             <Setter Property="ItemsControl.Background" Value="LightCoral"></Setter>
30         </Style>
31     </Window.Resources>
32     <StackPanel>
33         <Button x:Name="button1" Content="第一個按鈕" Style="{StaticResource first}"></Button>
34         <Button x:Name="button2" Content="第二個按鈕" Style="{StaticResource second}"></Button>
35         <Button x:Name="button3" Content="第三個按鈕" Style="{StaticResource third}"></Button>
36         <Button x:Name="button4" Content="第四個按鈕" Style="{StaticResource four}"></Button>
37     </StackPanel>
38 </Window>

 注意:如果樣式要被其他樣式繼承,則最好不要使用TargetType指定。一般情況下,可能為報錯【只能根據帶有基類型“IFrameworkInputElement”的目標類型的 Style。】

4. 樣式中綁定事件

在WPF中的樣式中,通過EventSetter進行事件綁定,如下所示:

示例源碼

在樣式中,通過EventSetter設置事件,如下所示:

 1 <Window x:Class="WpfApp1.SevenWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WpfApp1"
 7         mc:Ignorable="d"
 8         Title="基礎樣式示例" Height="250" Width="400">
 9     <Window.Resources>
10         <Style x:Key="base">
11             <Setter Property="Control.Margin" Value="2,5,2,5"></Setter>
12             <Setter Property="Control.FontFamily" Value="SimSun-ExtB"></Setter>
13             <Setter Property="Control.FontSize" Value="18"></Setter>
14         </Style>
15         <Style x:Key="first" BasedOn="{StaticResource base}">
16             <Setter Property="Control.Foreground" Value="Red"></Setter>
17             <Setter Property="Control.Background" Value="Gray"></Setter>
18             <EventSetter Event="Button.MouseEnter" Handler="FirstButton_MouseEnter"></EventSetter>
19         </Style>
20     </Window.Resources>
21     <StackPanel>
22         <Button x:Name="button1" Content="第一個按鈕" Style="{StaticResource first}"></Button>
23     </StackPanel>
24 </Window>

其中FirstButton_MouseEnter,文后台定義的一個事件函數,如下所示:

1  private void FirstButton_MouseEnter(object sender,MouseEventArgs e)
2 {
3       Button btn = (Button)sender;
4       MessageBox.Show("鼠標進入了 "+btn.Content.ToString()+" 呀!");
5 }

 觸發器

使用觸發器可自動完成簡單的樣式的改變,不需要使用代碼,也可以完成不少工作。觸發器通過Style.Trigger集合鏈接到樣式。每個樣式可以有任意多個觸發器。每個觸發器都是System.Windows.TriggerBase的實例。
TriggerBase的子類

 

 

1. 基礎觸發器

觸發器,是指當滿足一定條件,然后觸發相關的樣式設置,如下所示:

 示例源碼

示例中設置了兩個觸發器:1.Control.IsMouseOver鼠標覆蓋在按鈕上時,設置對應的樣式。2. Control.IsFocused,控件聚焦時,設置對應的樣式。如下所示:

 1 <Window x:Class="WpfApp1.EightWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WpfApp1"
 7         mc:Ignorable="d"
 8         Title="EightWindow" Height="350" Width="400">
 9     <Window.Resources>
10         <Style x:Key="first">
11             <Setter Property="Control.Margin" Value="2,5,2,5"></Setter>
12             <Setter Property="Control.FontFamily" Value="SimSun-ExtB"></Setter>
13             <Setter Property="Control.FontSize" Value="18"></Setter>
14             <Setter Property="Control.Foreground" Value="Red"></Setter>
15             <Setter Property="Control.Background" Value="LightBlue"></Setter>
16             <Style.Triggers>
17                 <Trigger Property="Control.IsMouseOver" Value="True">
18                     <Setter Property="ItemsControl.Background" Value="AliceBlue"></Setter>
19                     <Setter Property="Control.FontSize" Value="28"></Setter>
20                 </Trigger>
21                 <Trigger Property="Control.IsFocused" Value="True">
22                     <Setter Property="ItemsControl.Background" Value="DarkGoldenrod"></Setter>
23                     <Setter Property="Control.FontSize" Value="28"></Setter>
24                 </Trigger>
25             </Style.Triggers>
26         </Style>
27     </Window.Resources>
28     <StackPanel>
29         <Button x:Name="button1" Content="第一個按鈕" Style="{StaticResource first}"></Button>
30     </StackPanel>
31 </Window>

注意:如果樣式觸發器,設置了多個,且條件相互覆蓋時,以最后的設置為准。

2. 多條件觸發器

如果需要多個條件同時滿足,才能設置對應的樣式,則可以通過MultiTrigger來設置,如下所示:

 1 <Window x:Class="WpfApp1.EightWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WpfApp1"
 7         mc:Ignorable="d"
 8         Title="EightWindow" Height="350" Width="400">
 9     <Window.Resources>
10         <Style x:Key="first">
11             <Setter Property="Control.Margin" Value="2,5,2,5"></Setter>
12             <Setter Property="Control.FontFamily" Value="SimSun-ExtB"></Setter>
13             <Setter Property="Control.FontSize" Value="18"></Setter>
14             <Setter Property="Control.Foreground" Value="Red"></Setter>
15             <Setter Property="Control.Background" Value="LightBlue"></Setter>
16             <Style.Triggers>
17                 <MultiTrigger>
18                     <MultiTrigger.Conditions>
19                         <Condition Property="Control.IsMouseOver" Value="True"></Condition>
20                         <Condition Property="Control.IsFocused" Value="True"></Condition>
21                     </MultiTrigger.Conditions>
22                     <MultiTrigger.Setters>
23                         <Setter Property="ItemsControl.Background" Value="Gainsboro"></Setter>
24                         <Setter Property="Control.FontSize" Value="20"></Setter>
25                     </MultiTrigger.Setters>
26                 </MultiTrigger>
27             </Style.Triggers>
28         </Style>
29     </Window.Resources>
30     <StackPanel>
31         <Button x:Name="button1" Content="第一個按鈕" Style="{StaticResource first}"></Button>
32         <Button x:Name="button2" Content="第二個按鈕" ></Button>
33     </StackPanel>
34 </Window>

3. 事件觸發器

事件觸發器,是指某一個事件發生時,觸發的相關動作,主要用於動畫,如下所示:

示例源碼

當鼠標進入時,字體變大,當鼠標離開時,字體恢復,如下所示:

 1 <Window x:Class="WpfApp1.EightWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WpfApp1"
 7         mc:Ignorable="d"
 8         Title="EightWindow" Height="350" Width="400">
 9     <Window.Resources>
10         <Style x:Key="first">
11             <Setter Property="Control.Margin" Value="2,5,2,5"></Setter>
12             <Setter Property="Control.FontFamily" Value="SimSun-ExtB"></Setter>
13             <Setter Property="Control.FontSize" Value="18"></Setter>
14             <Setter Property="Control.Foreground" Value="Red"></Setter>
15             <Setter Property="Control.Background" Value="LightBlue"></Setter>
16             <Style.Triggers>
17                 <EventTrigger RoutedEvent="Mouse.MouseEnter" >
18                     <EventTrigger.Actions>
19                         <BeginStoryboard>
20                             <Storyboard>
21                                 <DoubleAnimation Duration="00:00:02" To="28" From="12" Storyboard.TargetProperty="FontSize"></DoubleAnimation>
22                             </Storyboard>
23                         </BeginStoryboard>
24                     </EventTrigger.Actions>
25                 </EventTrigger>
26                 <EventTrigger RoutedEvent="Mouse.MouseLeave">
27                     <EventTrigger.Actions>
28                         <BeginStoryboard>
29                             <Storyboard>
30                                 <DoubleAnimation Duration="00:00:01" Storyboard.TargetProperty="FontSize" To="18"  />
34                             </Storyboard>
35                         </BeginStoryboard>
36                     </EventTrigger.Actions>
37                 </EventTrigger>
38             </Style.Triggers>
39         </Style>
40     </Window.Resources>
41     <StackPanel>
42         <Button x:Name="button1" Content="第一個按鈕" Style="{StaticResource first}"></Button>
43         <Button x:Name="button2" Content="第二個按鈕" ></Button>
44     </StackPanel>
45 </Window>

備注

走進WPF,感受WPF之美,本文旨在拋磚引玉,共同學習,一起進步。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM