WPF基礎之樣式
阿新 • • 發佈:2019-01-06
樣式基礎
樣式(Style)是組織和重用格式化選項的重要工具。不是使用重複的標記填充XAML,以便設定外邊距、內邊距、顏色以及字型等細節,而是建立一系列封裝所有這些細節的樣式,然後再需要之處通過屬性來應用樣式。 樣式是可應用於元素的屬性值集合。使用資源的最常見原因之一就是儲存樣式。 使按鈕具有統一格式的實現方式一:資源<Window.Resources> <FontFamily x:Key="ButtonFontFamily">Times New Roman</這個示例可以正常工作,它將字型細節(所謂的magic number)移出的標記。但也存在兩個問題。FontFamily> <sys:Double x:Key="ButtonFontSize">18</sys:Double> <FontWeight x:Key="ButtonFontWeight">Bold</FontWeight> </Window.Resources> <Grid Name="gird1" ShowGridLines="True"> <Button FontFamily="{StaticResource ButtonFontFamily}" FontSize="{StaticResource ButtonFontSize}" FontWeight="{StaticResource ButtonFontWeight}"> </Button> </Grid>
- 除了資源的名稱相似之外,沒有明確指定三個資源是相關的。這使維護應用程式變得複雜。
- 需要使用資源的標記非常繁瑣。還沒有原來不使用資源時簡明。
<通過樣式系統不僅可以建立多組明顯相關的屬性設定,而且使得應用程式這些設定更加容易,從而精簡了標記。Window.Resources> <Style x:Key="BigFontButtonStyle"> <Setter Property="Control.FontFamily" Value="Times New Roman"/> <Setter Property="Control.FontSize" Value="18"/> <Setter Property="Control.FontWeight" Value="Bold"/> </Style> </Window.Resources> <Grid Name="gird1" ShowGridLines="True"> <Button Style="{StaticResource BigFontButtonStyle}"> </Button> </Grid>
設定屬性
每個Style物件都封裝了一個Setter物件的集合。每個Setter物件設定元素的單個屬性。在某些情況下不能使用簡單的特性字元設定屬性值。可使用巢狀的元素代替如:<Setter Property="Control.Background"> <Setter.Value> <ImageBrush TileMode="Tile" ViewboxUnits="Absolute" Viewport="0 0 32 32" ImageSource="" Opacity="0.3"></ImageBrush> </Setter.Value> </Setter>
建立只應用按鈕的樣式
<Style x:Key="BigFontButtonStyle" TargetType="Button"> <Setter Property="FontFamily" Value="Times New Roman"/> <Setter Property="FontSize" Value="18"/> <Setter Property="FontWeight" Value="Bold"/> </Style>
關聯事件處理程式
實現大量元素滑鼠懸停效果。<Window.Resources> <Style x:Key="MouseOverHighlightStyle"> <EventSetter Event="TextBlock.MouseEnter" Handler="element_MouseEnter"></EventSetter> <EventSetter Event="TextBlock.MouseLeave" Handler="element_MouseLeave"></EventSetter> </Style> </Window.Resources> <Grid Name="gird1" ShowGridLines="True"> <TextBlock Style="{StaticResource MouseOverHighlightStyle}"></TextBlock> </Grid>
多層樣式
每個WPF元素一次只能使用一個樣式物件,這像是一種限制,但由於屬性值的繼承和樣式繼承特性,這種限制實際是不存在的。例如,希望為一組控制元件使用相同的字型,又不想為每個控制元件應用相同的樣式。對於這種情況,可將他們放置到面板中,並設定容器的樣式。只要設定的屬性具有屬性值繼承特性,這些值就會傳遞到子元素。使用這種模型的屬性包括 IsEnabled、IsVisible、Foreground以及所有字型屬性。 另外一些情況,可能希望在另一個樣式的基礎上建立樣式,可用BasedOn特性。<Window.Resources> <Style x:Key="BigFontButtonStyle"> <Setter Property="Control.FontFamily" Value="Times New Roman"/> <Setter Property="Control.FontSize" Value="18"/> <Setter Property="Control.FontWeight" Value="Bold"/> </Style> <Style x:Key="NewBigButtonBigFontStyle" BasedOn="{StaticResource BigFontButtonStyle}"> <Setter Property="Control.Foreground" Value="Red"/> <Setter Property="Control.Background" Value="DarkBlue"/> </Style> </Window.Resources> <Grid Name="gird1" ShowGridLines="True"> <TextBlock Style="{StaticResource NewBigButtonBigFontStyle}">test</TextBlock> </Grid>
通過型別自動應用樣式
上面都是具有名稱的樣式,還有一種為特定型別元素自動應用的樣式。<Window.Resources> <Style TargetType="Button"> <Setter Property="Control.FontFamily" Value="Times New Roman"/> <Setter Property="Control.FontSize" Value="18"/> <Setter Property="Control.FontWeight" Value="Bold"/> </Style> </Window.Resources> <Grid Name="gird1" ShowGridLines="True"> <Button>one</Button> <Button Style="{x:Null}">two</Button> <Button>three</Button> </Grid>上面的例子中第二個按鈕顯示替換了樣式,將style設定為null,有效的刪除了樣式。
觸發器
使用觸發器可自動完成簡單的樣式的改變,不需要使用程式碼,也可以完成不少工作。 觸發器通過Style.Trigger集合連結到樣式。每個樣式可以有任意多個觸發器。每個觸發器都是System.Windows.TriggerBase的例項。 TriggerBase的子類名稱 | 說明 |
Trigger | 這是一種最簡單的觸發器。可以監測依賴項屬性的變化,然後設定器改變樣式。 |
MultiTrigger | 與Trigger類似,但這種觸發器聯合了多個條件。只有滿足了所有這些條件,才會啟動觸發器。 |
DataTrigger | 這種觸發器使用資料繫結,與Trigger類似,只不過監視的是任意繫結資料的變化。 |
MultiDataTrigger | 聯合多個數據觸發器。 |
EventTrigger | 這是最複雜的觸發器。當事件發生時,這種觸發器應用動畫。 |
簡單觸發器
可為任何依賴項屬性關聯簡單觸發器。例如,可通過相應Control類的IsFocused、IsMouseOver以及IsPressed屬性的變化,建立滑鼠懸停效果和焦點效果。 每個觸發器都制定了正在監視的屬性以及正在等待的屬性值。當屬性值出現時,將應用Trigger.Setters集合裡的設定器。<Window.Resources> <Style x:Key="BigFontButton"> <Style.Setters> <Setter Property="Control.FontFamily" Value="Times New Roman"/> <Setter Property="Control.FontSize" Value="18"/> <Setter Property="Control.FontWeight" Value="Bold"/> </Style.Setters> <Style.Triggers> <Trigger Property="Control.IsFocused" Value="True"> <Setter Property="Control.Foreground" Value="DarkRed"/> </Trigger> </Style.Triggers> </Style> </Window.Resources>觸發器的優點是不需要為翻轉他們而編寫任何程式碼。 如果希望幾個條件都滿足時才啟用觸發器,可使用MultiTrigger
<Style.Triggers> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Property="Control.IsFocused" Value="true"/> <Condition Property="Control.IsMouseOver" Value="true"/> </MultiDataTrigger.Conditions> <MultiDataTrigger.Setters> <Setter Property="Control.Foreground" Value="DarkRed"/> </MultiDataTrigger.Setters> </MultiDataTrigger> </Style.Triggers>
事件觸發器
普通觸發器等待屬性發生變化,而事件觸發器等待特定事件被引發。事件觸發器要求使用者提供一系列修改控制元件的動作。這些動作常用於動畫。 如監聽MouseEnter事件,然後動態改變按鈕的FontSize屬性從而形成動畫效果,在0.2秒的時間內容字型放大到22個單位。<Window.Resources> <Style x:Key="BigFontButton"> <Style.Setters> <Setter Property="Control.FontFamily" Value="Times New Roman"/> <Setter Property="Control.FontSize" Value="18"/> <Setter Property="Control.FontWeight" Value="Bold"/> </Style.Setters> <Style.Triggers> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:3" Storyboard.TargetProperty="FontSize" To="50"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> <EventTrigger RoutedEvent="Mouse.MouseLeave"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:3" Storyboard.TargetProperty="FontSize"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </Style.Triggers> </Style> </Window.Resources> <Grid Name="gird1" ShowGridLines="True"> <Button HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource BigFontButton}">onesfsfsfsfsdfsdf</Button> </Grid>
與屬性觸發器不同如果希望元素返回原始狀態,需要反轉事件觸發器。如上面例子,需要編寫MouseLeav事件的觸發器。不需要指明字型的大小,預設會恢復成第一次動畫之前的字型大小。