WPF中樣式和行為和觸發器


樣式簡介:樣式(style)是組織和重用格式化選項的重要工具,不是使用重復的標記填充XAML,以便設置外邊距、內邊距、顏色以及字體等細節。而是創建一系列封裝所有這些細節的樣式,然后在需要之處通過屬性來設置樣式。名稱空間是System.Windows。

1、樣式。

為了理解適合使用樣式的集合,分析一個簡單的示例,設想需要標准化在窗口中使用的字體,最簡單的方式是設置包含窗口的字體屬性,這些屬性都是在Control類中定義的,包括FontFamily、FontSize、FontWeight,得益於這些屬性值的繼承,當在窗口級別設置這些屬性時,窗口中的所有元素都會使用相同的屬性值。

定義一個普通的資源: 

<Window.Resources>        
    <!-- 定義一個FontFamily資源對象 -->
    <FontFamily x:Key="TextBlockFontFamily">楷體</FontFamily>
    <!-- 定義一個FontWeight資源對象 -->
    <FontWeight x:Key="TextBlockFontWeight">Bold</FontWeight>
</Window.Resources>

定義一個TextBlock,引用資源: 

 <TextBlock FontFamily="{StaticResource TextBlockFontFamily}" FontSize="30" FontWeight="{StaticResource TextBlockFontWeight}">今天天氣好晴朗!!!</TextBlock>

 在使用資源設置屬性時,正確地匹配類型是非常重要的,這個時候用到的是類型轉換器,如果為元素設置FontFamily對象,FontFamilyConverter轉換器會創建所需要的FontFamily對象。

這種寫法的弊端:

除了資源名稱相似外,並沒有明確指明這三個資源是相關的,這使維護變得非常復雜。

需要使用資源的標記非常繁瑣。

這個時候樣式就可以很好地解決這種解決方案(定義樣式): 

<Window.Resources>     
    <Style x:Key="TextBlockStyle">
        <Setter Property="Control.FontFamily" Value="楷體"></Setter>
        <Setter Property="Control.FontSize" Value="20"></Setter>
        <Setter Property="Control.FontWeight" Value="Bold"></Setter>
    </Style>
</Window.Resources>

名叫TextBlockStyle的樣式對象包含了一個設置器集合,該集合包含了三個Setter對象,每一個Setter對象用於一個希望設置的屬性,每個setter屬性對象由兩部分信息組成,分別是希望進行設置的屬性名稱和希望為該屬性應用的值。與所有資源一樣,樣式和對象都有一個鍵名。

在xaml中引用: 

<TextBlock Name="TextBlock1" Style="{StaticResource TextBlockStyle}">Hello,World!!!</TextBlock>

用代碼設置: 

TextBlock1.Style = (Style)FindResource("TextBlockStyle");

 2、Style類的常用屬性。 

Style類的常用屬性

屬性名

說明

Setters

 設置屬性值以及自動關聯事件處理程序的Setter對象或者EventSetter對象的集合。

Triggers

 繼承自TriggerBase類,並能自動改樣式設置對象的集合,例如當某個屬性改變時,或者是發生某個事件時,可以修改樣式。
 

Resources

 希望用於樣式的資源集合。
 

BaseOn

 通過該屬性可用於創建繼承自其他樣式設置的更具體形式。
 

TargetType

 該屬性標識應用央視的元素的類型,通過該屬性可創建只影響特定類型元素的設置器,還可以創建能夠為恰當的元素類型自動其作用的設置器。

 

 

 

 

 

 

 

 

 

 

 

 

 

3、創建樣式對象(嵌套元素)。

每一個Style對象都封裝了一個Setter對象的集合,每個Setter對象設置元素的單個屬性,只能設置依賴項屬性,不能修改其他屬性

<TextBlock Text="孤獨和迷茫時成長的必經之路!">
    <TextBlock.Style>
        <Style>
            <Setter Property="Control.FontWeight" Value="Bold"></Setter>
            <Setter Property="Control.FontSize" Value="20"></Setter>
        </Style>
    </TextBlock.Style>
</TextBlock>

 4、設置元素類型(TargetType)並自動應用樣式。

 通過TargetType指定類類型。如果去掉x:key特性,那么就會自動應用到元素類型了。將元素的Style屬性設置為x:Null 可取消自動應用樣式。

 <!--如果不寫x:key特性,就會自動為類元素設置style樣式了,不用再通過元素的style屬性設置樣式了。-->
    <Window.Resources>
        <Style TargetType="Button" >
            <Setter Property="Control.FontFamily" Value="楷體"></Setter>
            <Setter Property="Control.FontWeight" Value="Bold"></Setter>
            <Setter Property="Control.FontSize" Value="30"></Setter>
        </Style>
    </Window.Resources>

    <StackPanel>
        <Button Height="50">孤獨和時成長的必經之路!</Button>
        <!--通過x:Null取消樣式設置。-->
        <Button Height="50" Style="{x:Null}">孤獨和時成長的必經之路!</Button>
    </StackPanel>

 6、多層樣式(通過BaseOn繼承)。

盡管可在許多不同層次定義任意數量的樣式,但每個WPF元素一次只能使用一個樣式對象。這好像是一種限制,但由於屬性值繼承和樣式繼承特性,可通過BaseOn屬性繼承樣式即可。 如果兩次設置了同一個屬性,那么最后一次設置的樣式會覆蓋之前設置的樣式。

<Window.Resources>
    <!--設置一個字體樣式-->
    <Style x:Key="SetButtonFontSize">
        <Setter Property="Control.FontSize" Value="30"></Setter>
    </Style>

    <!--設置一個字體類型樣式,通過BaseOn屬性繼承字體大小樣式-->
    <Style x:Key="SetButtonFontFamily" BasedOn="{StaticResource SetButtonFontSize}">
        <Setter Property="Control.FontFamily" Value="楷體"></Setter>
    </Style>

    <!--設置一個字體粗細,通過BaseOn屬性繼承字體類型,這樣這個樣式就擁有了字體類型的字體大小的樣式了-->
    <Style x:Key="SetButtonBold" BasedOn="{StaticResource SetButtonFontFamily}">
        <Setter Property="Control.FontWeight" Value="Bold"></Setter>
     <!--如果再設置字體大小,那么就以最后一次設置為准。-->
        <Setter Property="Control.FontSize" Value="40"></Setter>
    </Style>
</Window.Resources>

<StackPanel>
    <Button Style="{StaticResource SetButtonBold}">Hello,World!!!</Button>
</StackPanel>

 7、觸發器(Trigger)。

WPF有個主題,就是以聲明的方式擴展代碼的功能,當使用樣式、資源或者數據綁定時,將發現即使不適用代碼,也能完成不少工作,這個時候就要使用觸發器了,當屬性發生變化時,可以進行響應,並自動調整樣式。每個樣式可以有任意多個觸發器,而且每個觸發器都是System.Windows.TriggerBase的派生類的實例。

簡單理解就是:在樣式中設置觸發器,在觸發器中設置屬性名稱和屬性值。

繼承自TriggerBase的類

Trigger

這是一種簡單的觸發器,可以監測依賴項屬性的變化,然后使用設置器改變樣式

MultiTrigger

與Trigger類似,但這種觸發器聯合了多個條件,只有滿足了所有這些條件,才會啟動出觸發器

DataTrigger

數據綁定觸發器

MultiDataTrigger

聯合多個數據觸發器

EventTrigger

這是復雜的觸發器,當事件發生時,這種觸發器應用動畫

 

 

 

 

 

 

 

 

 

 

7.1、簡單觸發器。

可以為任何依賴項屬性關聯簡單觸發器,每個簡單的觸發器都指定了正在監視的屬性,以及正在等待的屬性值,當屬性值出現時,將應用存儲在Trigger.Setters集合中的設置器(不能使用復雜的觸發器邏輯)。

<Window.Resources>
    <Style x:Key="BigFontButton">
        <Style.Setters>
            <Setter Property="Control.FontSize" Value="30"></Setter>
            <Setter Property="Control.FontFamily" Value="楷體"></Setter>
        </Style.Setters>

        <!--在樣式中設置觸發器-->
        <Style.Triggers>
            <!--如果元素獲取了焦點。-->
            <Trigger Property="Control.IsFocused" Value="true">
                <!--設置其中的元素屬性。設置前景色為紫色。-->
                <Setter Property="Control.Foreground" Value="Pink"></Setter>
            </Trigger>                
        </Style.Triggers>
    </Style>

    <!--設置一個簡單的觸發器,在觸發器中改變元素的背景色。-->
    <Style x:Key="SetButton">
        <Style.Triggers>
            <Trigger Property="Control.IsFocused" Value="true">
                <Setter Property="Control.Background" Value="Yellow"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>        
</Window.Resources>

<StackPanel>
    <!--設置第一個樣式-->
    <Button Style="{StaticResource BigFontButton}">Hello,World!!!</Button>      
    <!--設置第二個樣式-->    
    <Button Style="{StaticResource SetButton}" Height="50" FontSize="30">Hello,World!!!</Button>
</StackPanel>  

 7.2、為元素設置樣式(嵌套形式)。 

<Button Height="50" FontSize="30" Content="今天天氣好晴朗!!!">
    <Button.Style>
        <Style>
            <Style.Triggers>
                <Trigger Property="Control.IsMouseOver" Value="true">
                    <!--可將S屬性樣式寫在Trigger.Setters中(方式一)-->
                    <!--<Trigger.Setters> <Setter Property="Control.Foreground" Value="Red"></Setter> </Trigger.Setters>-->

                    <!--(方式二)-->
                    <!--也可以直接寫在Triggr中,視情況而定,如果觸發器滿足多個條件時,要使用第一種方式設置屬性值。-->
                    <Setter Property="Control.Foreground" Value="Red"></Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

 7.3、MultiTrigger觸發器(滿足多條件的觸發器)。

如果希望創建只有當幾個條件都為真時才激活的觸發器,可使用MultiTrigger,這種觸發器提供了一個Conditions(條件)集合,可通過該集合定義一系列屬性值的集合。

<Window.Resources>
    <Style x:Key="SetButton">
        <!--觸發器-->
        <Style.Triggers>
            <!--使用多條件觸發器-->
            <MultiTrigger>
                <!--通過Conditions屬性設置多個條件(一個是獲取焦點和鼠標移動到元素上。)。-->
                <MultiTrigger.Conditions>
                    <Condition Property="Control.IsFocused" Value="true"></Condition>
                    <Condition Property="Control.IsMouseOver" Value="true"></Condition>
                </MultiTrigger.Conditions>

                <!--設置多個屬性值-->
                <MultiTrigger.Setters>
                    <Setter Property="Control.FontSize" Value="30"></Setter>
                </MultiTrigger.Setters>                    
            </MultiTrigger>                
        </Style.Triggers>
    </Style>
</Window.Resources>

<StackPanel>
    <!--設置樣式。-->
    <Button Style="{StaticResource SetButton}">Hello,World!!!</Button>
</StackPanel>

 7.4、事件觸發器。

普通觸發器是等待屬性發生變化,而事件觸發器是等待特定的事件被引發。事件觸發器要求用戶提供一系列修改控件的動作,這些動作通常被應用為動畫。 

<Window.Resources>
    <Style x:Key="SetButtonMouseOver">
        <!--設置觸發器-->
        <Style.Triggers>
            <!--設置觸發器的路由事件-->
            <EventTrigger RoutedEvent="Control.MouseEnter">
                <!--設置一個動畫,改變元素的字體的大小-->
                <EventTrigger.Actions>
                    <BeginStoryboard>                            
                        <Storyboard>
                             <DoubleAnimation Duration="0:0:0:2" Storyboard.TargetProperty="FontSize" To="30"></DoubleAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger.Actions>
            </EventTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<StackPanel>
    <!--設置樣式-->
    <Button Style="{StaticResource SetButtonMouseOver}">Hello,World!!!</Button>
</StackPanel>

 End!


免責聲明!

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



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