WPF 10天修煉 第七天- WPF資源、樣式、控件模板

WPF資源

對象資源 express

WPF容許在XAML標記的任意位置定義資源。好比在特定的控件、窗口或應用程序級別定義資源,WPF資源系統提供的對象資源有以下好處:性能

一、  高效:使用對象資源能夠在一個地方定義而在多個地方使用,這使得WPF代碼可重用一些對象信息。字體

二、  可維護:能夠將一些設置信息放置在一箇中心位置,並在多個地方使用。若是須要進行更改時,只須要在中心位置進行更改,方便代碼的維護工做。spa

三、  可適應性:當肯定的信息從應用程序中分離出來放在資源中,就能夠動態地被改變。例如能夠基於用戶的偏好設置當前語言來更改信息。3d

 下面是一個在Grid級別的資源,設置textblock的字體大小。 orm

<Window x:Class="WPFDemo.Resource_FontSize"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFDemo"
        xmlns:s="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="Resource_FontSize" Height="300" Width="300" 
        >
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <!---Grid級別的資源-->
        <Grid.Resources>
            <s:Double x:Key="SmallSize" >20</s:Double>
            <s:Double x:Key="LargeSize">30</s:Double>
        </Grid.Resources>
        <TextBlock Text="小字體" Grid.Row="0">
            <TextBlock.FontSize>
                <StaticResource ResourceKey="SmallSize" />
            </TextBlock.FontSize>
        </TextBlock>
        <TextBlock Text="大字體" Grid.Row="1">
            <TextBlock.FontSize>
                <StaticResource ResourceKey="LargeSize" />
            </TextBlock.FontSize>
        </TextBlock>
    </Grid>
</Window>

  

 

靜態資源xml

靜態資源就是上面使用StaticResource標記引用的資源。這種資源一旦被建立就不會被改變。靜態資源必須先定義資源,不然會拋出異常。對象

應用程序資源blog

應用程序的資源做用域覆蓋整個WPF應用程序,WPF將按照元素、窗口、應用程序、系統資源的順序進行資源查找。當新建一個WPF項目時,在APP.xaml中會自動添加<Application.Resources>標籤,能夠在標籤內添加應用程序級別的資源。繼承

定義BackgroundColor系統資源

<Application x:Class="WPFDemo.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             StartupUri="Resource-FontSize.xaml"
             >
    <Application.Resources>
        <SolidColorBrush x:Key="BackgroundColor" Color="Yellow">        
       </SolidColorBrush>
    </Application.Resources>
</Application>

 

調用BackgrouundColor資源 

在Window標籤添加引用  Background="{StaticResource BackgroundColor}"

<Window x:Class="WPFDemo.Resource_FontSize"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFDemo"
        xmlns:s="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="Resource_FontSize" Height="300" Width="300"
        Background="{StaticResource BackgroundColor}"
        >
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <!---Grid級別的資源-->
        <Grid.Resources>
            <s:Double x:Key="SmallSize" >20</s:Double>
            <s:Double x:Key="LargeSize">30</s:Double>
        </Grid.Resources>
        <TextBlock Text="小字體" Grid.Row="0">
            <TextBlock.FontSize>
                <StaticResource ResourceKey="SmallSize" />
            </TextBlock.FontSize>
        </TextBlock>
        <TextBlock Text="大字體" Grid.Row="1">
            <TextBlock.FontSize>
                <StaticResource ResourceKey="LargeSize" />
            </TextBlock.FontSize>
        </TextBlock>
    </Grid>
</Window>

 

使用資源字典組織資源 

能夠在一個單獨的XAML文件中定義資源,而後該資源能夠在多個項目進行共享。獨立的資源文件使用ResourceDictionary做爲根元素。該XAML文件除了用於存儲資源外,不能作任何其餘的工做。

下面定義一個線性漸變的背景色

一、  首先新建WPF資源文件添加資源內容

二、  將資源文件設置生成操做位Page以確保資源被做爲BAML文件編譯。也能夠將其指定爲Reesource,這種方式將內嵌在程序集中,不被編譯,運行時編譯,性能開支較大。

三、爲了使用該資源,須要將其合併到應用程序資源集合中,能夠合併到指定窗口資源集合,可是一般合併到應用程序級別的集合。

 

新建WPF資源文件並添加內容

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:WPFDemo">
    <!--定義漸變的背景色-->
    <LinearGradientBrush x:Key="brushLinear">
        <LinearGradientBrush.GradientStops>
            <GradientStop Color="Red" Offset="0" />
            <GradientStop Color="Yellow" Offset="0.5" />
            <GradientStop Color="Blue" Offset="1" />
        </LinearGradientBrush.GradientStops>
    </LinearGradientBrush> 
</ResourceDictionary>

將資源文件合併到應用程序資源中

 

<Application x:Class="WPFDemo.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
             StartupUri="Resource-FontSize.xaml" 
             >
    <Application.Resources> 
        <ResourceDictionary>
            <SolidColorBrush x:Key="BackgroundColor" Color="Yellow"></SolidColorBrush>
            <ResourceDictionary.MergedDictionaries> 
                <ResourceDictionary Source="DictionaryDemo.xaml" />
            </ResourceDictionary.MergedDictionaries> 
        </ResourceDictionary>
    </Application.Resources>
</Application>

在上面的例子中增長一個button按鈕將其背景顏色設置爲漸變

<Window x:Class="WPFDemo.Resource_FontSize"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFDemo"
        xmlns:s="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="Resource_FontSize" Height="300" Width="300" 
        Background="{StaticResource BackgroundColor}"
        >
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <!---Grid級別的資源-->
        <Grid.Resources>
            <s:Double x:Key="SmallSize" >20</s:Double>
            <s:Double x:Key="LargeSize">30</s:Double>
        </Grid.Resources>
        <TextBlock Text="小字體" Grid.Row="0">
            <TextBlock.FontSize>
                <StaticResource ResourceKey="SmallSize" />
            </TextBlock.FontSize>
        </TextBlock>
        <TextBlock Text="大字體" Grid.Row="1">
            <TextBlock.FontSize>
                <StaticResource ResourceKey="LargeSize" />
            </TextBlock.FontSize>
        </TextBlock> 
        <Button Grid.Row="2" Content="我是應用靜態資源的漸變色">
            <Button.Background>
                <StaticResource ResourceKey="brushLinear" />
            </Button.Background> 
        </Button>
    </Grid>
</Window>

WPF樣式

樣式是WPF中功能強大的特性,樣式基於資源,可是比資源提供了更多重用代碼特性。樣式與資源相比,提供了額外的好處來使XAML更具可重用性和擴展性。假設在UI中有幾個button控件。須要提供3中不一樣的顯示風格。例如不一樣的FontSize ,FontFamily 和FontWeight 3個屬性。此時可能會考慮使用資源的辦法,使用該資源能夠完成該功能,可是若是每一個屬性設置3中資源,將會有9中資源出現。在這裏使用WPF的樣式功能能夠輕鬆解決這些問題。

 樣式設置優先級:

優先級

描述

元素(高)

元素自己定義的屬性具備最高的優先級

樣式(中)

在樣式中定義的相同屬性

父元素(低)

從視覺樹的父元素中繼承下來的屬性

 下面實例中會將樣式的各類用法都涉及到:主要包括基本的樣式、內聯樣式、在樣式中設置屬性的複雜應用、根據指定類型自動應用樣式。

<Window x:Class="WPFDemo.StyleDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFDemo"
        mc:Ignorable="d"
        Title="StyleDemo" Height="300" Width="300">
    <Window.Resources>
        <!--基本樣式 button 按鈕樣式-->
        <Style x:Key="ButtonStyle">
            <Setter Property="Control.FontFamily" Value="楷體"></Setter>
            <Setter Property="Control.FontSize" Value="20"></Setter>
        </Style>
        <!--基本樣式 Textblock樣式-->
        <Style x:Key="TextBlockStyle">
            <Setter Property="Control.FontFamily" Value="楷體"></Setter>
            <Setter Property="Control.FontSize" Value="40"></Setter>
        </Style>
        <!--僅限Button使用-->
        <Style x:Key="buttonBackgroundColor">
            <Setter Property="Button.Background" Value="LightGreen"></Setter>
        </Style>
        <!--使用TargetType指定樣式使用的控件類型  自動套用樣式-->
        <Style TargetType="{x:Type Label}">
            <Setter Property="Foreground" Value="Red"></Setter>
            <Setter Property="FontSize" Value="30"></Setter>
        </Style>
        <!--控件基類樣式-->
        <Style x:Key="BaseStyle">
            <Setter Property="Control.FontSize" Value="20"></Setter>
        </Style>
        <!--繼承BaseStyle-->
        <Style x:Key="BaseButtonSyle" BasedOn="{StaticResource BaseStyle}">
            <Setter Property="Control.Foreground" Value="Red"></Setter>
            <Setter Property="Control.FontWeight" Value="Bold"></Setter>
        </Style>
    </Window.Resources>
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Content="應用樣式按鈕" Style="{StaticResource ButtonStyle}"></Button>
        <Button Grid.Row="1" FontSize="10" Content="應用樣式按鈕並設置字體大小" ></Button>
        <TextBlock Grid.Row="2" Text="應用樣式文本" Style="{StaticResource TextBlockStyle}"></TextBlock>
        <TextBlock Grid.Row="3" Text="沒有應用樣式文本" ></TextBlock>
        <Button Grid.Row="4"  FontSize="10" Content="使用內聯樣式設置字體爲紅色 背景爲黃色" >
            <!--內聯樣式-->
            <Button.Style>
                <Style>
                    <Setter Property="Control.Foreground" Value="Red"></Setter>
                    <Setter Property="Control.Background" Value="Yellow"></Setter>
                </Style>
            </Button.Style>
        </Button>
        <Button Grid.Row="5" Content="設置背景色爲漸變(在樣式中使用屬性)">
            <!--樣式中使用屬性-->
            <Button.Style>
                <Style>
                    <Setter Property="Button.Background">
                        <Setter.Value>
                            <LinearGradientBrush  StartPoint="0,0" EndPoint="1,1">
                                <LinearGradientBrush.GradientStops>
                                    <GradientStop Color="Red" Offset="0"/>
                                    <GradientStop Color="Yellow" Offset="0.5"/>
                                    <GradientStop Color="Blue" Offset="1"/>
                                </LinearGradientBrush.GradientStops>
                            </LinearGradientBrush>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Button.Style>
        </Button>
        <Button Grid.Row="6" Content="我是button,我設置了button樣式 - 背景爲LightGreen,起做用" Style="{StaticResource buttonBackgroundColor}"></Button>
        <TextBlock Grid.Row="7" Text="我是textblock,我設置了button樣式 - 背景爲LightGreen;不起做用" Style="{StaticResource buttonBackgroundColor}"></TextBlock>
        <Label Grid.Row="8"   Content="我是Label,Target設置Label 我自動套用Label樣式 字體爲30 字體爲紅色"></Label>
        <Button Grid.Row="9" Style="{StaticResource BaseButtonSyle}" Content="我使用的是繼承樣式"></Button>
    </Grid>
</Window>

 

樣式觸發器

Style類提供了Triggers集合,每一個樣式能夠有多個觸發器,每一個觸發器是一個派生自System.Windows.TriggerBase類的實例。在WPF中,繼承自TriggerBase的觸發器有下面的類型(屬性觸發器、數據觸發器、事件觸發器):

一、Trigger:簡單觸發器,該觸發器檢查特定的依賴的屬性的值是否發生變化來使用Setter改變樣式。

二、MultiTrigger:相似於簡單觸發器,可是組合了多個條件,全部的條件必須被知足纔會改變樣式。

三、DataTrigger:與簡單觸發器相似,該觸發器與數據綁定一塊兒運行。可是該觸發器是檢測任何綁定的數據是否發生變化。

四、MultiDataTrigger:組合了多個DataTrigger。

五、EventTrigger:這是最經常使用的觸發器,當某個事件觸發時來改變樣式。

 

在觸發器中若是多個觸發器修改相同的屬性,則最後觸發的觸發器優先。

<Window x:Class="WPFDemo.StyleTriggerDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFDemo"
        mc:Ignorable="d"
        Title="StyleTriggerDemo" Height="300" Width="300">
    <Window.Resources>
        <!--屬性觸發器 按下鼠標後字體增大 按鈕旋轉20度-->
        <Style x:Key="buttonStyle" TargetType="{x:Type Button}">
            <Style.Triggers>
                <Trigger Property="IsPressed" Value="True">
                    <Setter Property="RenderTransform">
                        <Setter.Value>
                            <RotateTransform Angle="20" />
                        </Setter.Value>
                    </Setter>
                    <Setter Property="Foreground" Value="Black"/>
                    <Setter Property="FontSize" Value="20"></Setter>
                </Trigger>
            </Style.Triggers>
            <Setter Property="FontSize" Value="10"></Setter>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Background" Value="#FF87F16F"/>
            <Setter Property="Width" Value="100"></Setter>
            <Setter Property="Height" Value="50" />
        </Style>

        <!--多條件屬性觸發器 鼠標通過時顯示字體顏色爲黃色;鼠標按下而且字體爲20時設置字體顏色爲紅色-->
        <Style x:Key="buttonStyle-Multi" TargetType="{x:Type Button}">
            <Setter Property="FontSize" Value="20" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Foreground" Value="Yellow" />
                </Trigger>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsPressed" Value="True"/>
                        <Condition Property="FontSize" Value="20"/>
                    </MultiTrigger.Conditions>
                    <MultiTrigger.Setters>
                        <Setter Property="Foreground" Value="Red"></Setter>
                    </MultiTrigger.Setters>
                </MultiTrigger>
            </Style.Triggers>

        </Style>

        <!--事件觸發器-->
        <Style x:Key="buttonClickStyle">
            <Setter Property="Control.FontSize" Value="20"></Setter>
            <!--定義事件觸發器-->
            <Style.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.1" To="1" Duration="0:0:2"></DoubleAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Style.Triggers>
        </Style> 
        <!--數據觸發器-->
        <Style x:Key="DataTextTrigger">
            <!---將控件的背景色設置爲文本框中輸入的顏色-->
            <Setter Property="Control.Background" Value="{Binding RelativeSource={RelativeSource Self},Path=Text}"></Setter>
            <Style.Triggers>
                <!--當文本中輸入的字符超過20時,則文本框的Enable爲false-->
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=Text.Length}" Value="20">
                    <Setter Property="Control.IsEnabled" Value="False"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style> 
        <!--多條件數據觸發器-->
        <Style x:Key="DataTextTrigger-Multi">
            <Setter Property="Control.FontSize" Value="20"></Setter>
            <Setter Property="Control.Margin" Value="10" ></Setter>
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding ElementName=cb1,Path=IsChecked}" Value="True"></Condition>
                        <Condition Binding="{Binding ElementName=cb2,Path=IsChecked}" Value="True"></Condition>
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.Setters>
                        <Setter Property="Control.Background" Value="Red"></Setter>
                    </MultiDataTrigger.Setters>
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions> 
        <Button Grid.Row="0"   Name="but" Style="{StaticResource buttonStyle}" Content="屬性觸發器"/>
        <Button Grid.Row="1" Style="{StaticResource buttonStyle-Multi}"  Content="多條件屬性觸發器"/>
        <Button Grid.Row="2" Content="按鈕" Style="{StaticResource buttonClickStyle}"></Button>
        <TextBox Grid.Row="3" Margin="10" Style="{StaticResource DataTextTrigger}" Text="LightBlue"></TextBox>
        <StackPanel Grid.Row="4" Name="panel1" Style="{StaticResource DataTextTrigger-Multi}">
            <CheckBox Name="cb1" >全選後改變背景顏色</CheckBox>
            <CheckBox Name="cb2" >全選後改變背景顏色</CheckBox>
        </StackPanel>
    </Grid>
</Window>

 

控件模板

在WPF中,每一個控件都有一個默認的控件模板,用於定義控件的基本外觀和行爲。WPF使用ControlTemplate定義控件的外觀,每一個控件都有一個Template的屬性。默認狀況下。控件經過該屬性獲取呈現的外觀,經過更改ControlTemplate,能夠爲控件定義一個新的樣式

<Window x:Class="WPFDemo.TemplateDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFDemo"
        mc:Ignorable="d"
        Title="TemplateDemo" Height="300" Width="300">
    <Window.Resources>
        <ControlTemplate x:Key="ButtomTemplate" TargetType="{x:Type Button}">

            <Border Name="Border" BorderBrush="{TemplateBinding Foreground}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    CornerRadius="5" Background="{TemplateBinding Background}"
                    TextBlock.Foreground="{TemplateBinding Foreground}"
                    Margin="{TemplateBinding Margin}">
                <ContentPresenter RecognizesAccessKey="True"
                                  HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                                  VerticalAlignment="{TemplateBinding VerticalAlignment}">

                </ContentPresenter>
            </Border>
            <!--設置模板觸發器-->
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver"  Value="True">
                    <Setter TargetName="Border" Property="Background" Value="Red"></Setter>
                </Trigger>
                <Trigger Property="IsPressed" Value="True">
                    <Setter TargetName="Border" Property="Background" Value="Yellow"></Setter>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Window.Resources>
    <Grid> 

        <Button   Template="{StaticResource ButtomTemplate}" Margin="10" Background="LightBlue" Content="我是套用模板的button"></Button>
    </Grid>
</Window>

相關文章
相關標籤/搜索