WPF样式的使用

一.样式的定义

1.不显式定义key标记

当样式中没有定义key标记时,则对应的样式会指定应用到所有的目标对象上。如果要 使其不引用事先定义的样式,使用 Style =" {x:Null} "

<Window x:Class="StyleDemo.StyleDefineAndUse"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="400">
    <Window.Resources>
        
        <Style TargetType="Button">
            <Setter Property="FontFamily" Value="Times New Roman" />
            <Setter Property="FontSize" Value="18" />
            <Setter Property="FontWeight" Value="Bold" />
        Style>
    Window.Resources>
    <StackPanel Margin="5">
        
        <Button Padding="5" Margin="5">Customized ButtonButton>
        <TextBlock Margin="5">Normal Content.TextBlock>
        
        <Button Padding="5" Margin="5" Style="{x:Null}">A Normal ButtonButton>
    StackPanel>
Window>
具体的运行效果如下图所示:
WPF样式的使用_第1张图片

2.显式定义key

如果显式为样式定义了key标记的话,则必须显式指定样式Key的方式,对应的样式才会被应用到目标对象上
<Window x:Class="StyleDemo.ReuseFontWithStyles"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ReuseFontWithStyles" Height="300" Width="300">
    <Window.Resources>
        
        <Style TargetType="Button" x:Key="BigButtonStyle">
            <Setter Property="FontFamily" Value="Times New Roman" />
            <Setter Property="FontSize" Value="18" />
            <Setter Property="FontWeight" Value="Bold" />
        Style>
    Window.Resources>
    <StackPanel Margin="5">
        
        <Button Padding="5" Margin="5">Normal ButtonButton>
        <Button Padding="5" Margin="5" Style="{StaticResource BigButtonStyle}">Big ButtonButton>
        <TextBlock Margin="5">Normal Content.TextBlock>
        
        <Button Padding="5" Margin="5" Style="{x:Null}">A Normal ButtonButton>
    StackPanel>
Window>
具体的运行效果如下图所示:
WPF样式的使用_第2张图片

3.BasedOn属性:通过设置BasedOn属性,可以继承某个样式

  1. <Window.Resources>  
  2.       
  3.     <Style x:Key="gBut" TargetType="{x:Type Button}">  
  4.           
  5.         <Setter Property="Cursor" Value="Hand"/>  
  6.           
  7.         <Setter Property="Width" Value="150"/>  
  8.           
  9.         <Setter Property="Height" Value="80"/>  
  10.     Style>  
  11.           
  12.       
  13.     <Style x:Key="cBtn1" TargetType="{x:Type Button}" BasedOn="{StaticResource gBut}">  
  14.           
  15.         <Setter Property="Background" Value="Black"/>  
  16.           
  17.         <Setter Property="FontSize" Value="24"/>  
  18.           
  19.         <Setter Property="Foreground" Value="Blue"/>  
  20.           
  21.         <Setter Property="Margin" Value="20"/>  
  22.     Style>  
  23.   
  24.       
  25.     <Style x:Key="cBtn2" TargetType="{x:Type Button}" BasedOn="{StaticResource gBut}">  
  26.           
  27.         <Setter Property="Background" Value="White"/>  
  28.           
  29.         <Setter Property="FontSize" Value="24"/>  
  30.           
  31.         <Setter Property="Foreground" Value="Red"/>  
  32.           
  33.         <Setter Property="Margin" Value="10"/>  
  34.     Style>  
  35. Window.Resources>

二.样式触发器

1.属性触发器

  WPF样式还支持触发器,在样式中定义的触发器,只有在该属性或事件发生时才会被触发,下面具体看看简单的样式触发器是如何定义和使用的,具体的XAML代码如下所示:

<Window x:Class="StyleDemo.SimpleTriggers"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SimpleTriggers" Height="300" Width="300">
    <Window.Resources>
        <Style x:Key="BigFontButton">
            <Style.Setters>
                <Setter Property="Control.FontFamily" Value="Times New Roman" />
                <Setter Property="Control.FontSize" Value="18" />

            Style.Setters>
            
            <Style.Triggers>
                
                <Trigger Property="Control.IsFocused" Value="True">
                    <Setter Property="Control.Foreground" Value="Red" />
                Trigger>
                
                <Trigger Property="Control.IsMouseOver" Value="True">
                    <Setter Property="Control.Foreground" Value="Yellow" />
                    <Setter Property="Control.FontWeight" Value="Bold" />
                Trigger>
                
                <Trigger Property="Button.IsPressed" Value="True">
                    <Setter Property="Control.Foreground" Value="Blue" />
                Trigger>
            Style.Triggers>
        Style>
    Window.Resources>

    <StackPanel Margin="5">
        <Button Padding="5" Margin="5"
            Style="{StaticResource BigFontButton}" 
              >A Big ButtonButton>
        <TextBlock Margin="5">Normal Content.TextBlock>
        <Button Padding="5" Margin="5"
            >A Normal ButtonButton>
    StackPanel>
Window>

  此时的运行效果如下图所示:

WPF样式的使用_第3张图片

2.事件触发器

  上面定义的触发器都是在某个属性发生变化时触发的,也可以定义当某个事件激活时的触发器,我们也把这样的触发器称为事件触发器,下面示例定义的事件触发器是等待MouseEnter事件,一旦触发MouseEnter事件,则动态改变按钮的FontSize属性来形成动画效果,具体的XAML代码如下所示:

<Window x:Class="StyleDemo.EventTrigger"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="EventTrigger" Height="300" Width="300">
    <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:0.2"
                  Storyboard.TargetProperty="FontSize"
                  To="22"  />
                            Storyboard>
                        BeginStoryboard>
                    EventTrigger.Actions>
                EventTrigger>
                
                <EventTrigger RoutedEvent="Mouse.MouseLeave">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            
                            
                            <Storyboard>
                                <DoubleAnimation
                  Duration="0:0:1"
                  Storyboard.TargetProperty="FontSize"  />
                            Storyboard>
                        BeginStoryboard>
                    EventTrigger.Actions>
                EventTrigger>
            Style.Triggers>
        Style>     
    Window.Resources>
    <StackPanel Margin="5">
        <Button Padding="5" Margin="5"
            Style="{StaticResource BigFontButton}" 
              >A Big ButtonButton>
        <TextBlock Margin="5">Normal Content.TextBlock>
        <Button Padding="5" Margin="5"
            >A Normal ButtonButton>
    StackPanel>
Window>

  此时的运行效果如下图所示:

WPF样式的使用_第4张图片

3.MultiTrigger

MultiTrigger是个容易让人误解的名字,会让人以为是多个Trigger集成在一起,实际上叫MultiConditionTrigger更合适,因为必须多个条件同时成立时才会触发。MultiTrigger比Trigger多了一个Conditions属性,需要同时成立的条件就储存在这个集合中。
  1. <Window.Resources>  
  2.     <Style TargetType="CheckBox">  
  3.         <Style.Triggers>  
  4.             <MultiTrigger>  
  5.                 <MultiTrigger.Conditions>  
  6.                     <Condition Property="IsChecked" Value="true"/>  
  7.                     <Condition Property="Content" Value="正如我悄悄的来"/>  
  8.                 MultiTrigger.Conditions>  
  9.                 <MultiTrigger.Setters>  
  10.                     <Setter Property="FontSize" Value="20"/>  
  11.                     <Setter Property="Foreground" Value="Orange"/>  
  12.                 MultiTrigger.Setters>  
  13.             MultiTrigger>  
  14.         Style.Triggers>  
  15.     Style>  
  16. Window.Resources>  
  17.       
  18. <StackPanel>  
  19.     <CheckBox Content="悄悄的我走了" Margin="5"/>  
  20.     <CheckBox Content="正如我悄悄的来" Margin="5,0"/>  
  21.     <CheckBox Content="我挥一挥衣袖" Margin="5"/>  
  22.     <CheckBox Content="不带走一片云彩" Margin="5,0"/>  
  23. StackPanel>  

4.由数据触发的DataTrigger

程序中经常会遇到基于数据执行某些判断情况,遇到这种情况时我们可以考虑使用DataTrigger。DataTrigger对象的Binding属性会把数据源不断送过来,一旦送了的值与Value属性一致,DataTrigger即被触发。

下面例子中,当TextBox的Text长度小于7个字符时其Border会保持红色。XAML代码如下:

  1. <Window x:Class="WpfApplication1.MainWindow"  
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.         xmlns:local="clr-namespace:WpfApplication1"  
  5.         Title="WPF样式的使用" Height="500" Width="800" WindowStartupLocation="CenterScreen">  
  6.     <Window.Resources>  
  7.         <local:L2BConverter x:Key="cvtr" />  
  8.         <Style TargetType="TextBox">  
  9.             <Style.Triggers>  
  10.                 <DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self},Path=Text.Length,Converter={StaticResource cvtr}}" Value="false">  
  11.                     <Setter Property="BorderBrush" Value="Red"/>  
  12.                     <Setter Property="BorderThickness" Value="1"/>  
  13.                 DataTrigger>  
  14.             Style.Triggers>  
  15.         Style>  
  16.     Window.Resources>  
  17.       
  18.     <StackPanel>  
  19.         <TextBox Margin="5"/>  
  20.         <TextBox Margin="5,0"/>  
  21.         <TextBox Margin="5"/>  
  22.     StackPanel>  
  23. Window> 
这里用到了Converter,我们创建如下的Converter:
  1. using System;  
  2. using System.Windows.Data;  
  3.   
  4. namespace WpfApplication1  
  5. {  
  6.     public class L2BConverter : IValueConverter  
  7.     {  
  8.         public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
  9.         {  
  10.             int textLength = (int)value;  
  11.             return textLength > 6 ? true : false;  
  12.         }  
  13.   
  14.         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
  15.         {  
  16.             throw new NotImplementedException();  
  17.         }  
  18.     }  
经Converter转换后,长度值会转换成bool类型值。DataTrigger的Value被设置为false,也就是说当TextBox的文本长度小于7时DataTrigger会使用自己的一组Setter把TextBox的边框设置为红色。

5.多条件触发的MultiDataTrigger

有时候我们会遇到要求多个数据条件同时满足时才能触发变化的需求,此时可以考虑使用MultiDataTrigger。比如有这样一个需求:用户界面使用ListBox显示了一列Student数据,当Student对象同时满足ID为2、Name为Tom的时候,条目就高亮显示,XAML代码如下:
  1. <Window x:Class="WpfApplication1.MainWindow"  
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.         xmlns:local="clr-namespace:WpfApplication1"  
  5.         Title="WPF样式的使用" Height="500" Width="800" WindowStartupLocation="CenterScreen">  
  6.     <Window.Resources>  
  7.         <Style TargetType="ListBoxItem">  
  8.               
  9.             <Setter Property="ContentTemplate">  
  10.                 <Setter.Value>  
  11.                     <DataTemplate>  
  12.                         <StackPanel Orientation="Horizontal">  
  13.                             <TextBlock Text="{Binding ID}" Width="60"/>  
  14.                             <TextBlock Text="{Binding Name}" Width="120"/>  
  15.                             <TextBlock Text="{Binding Age}" Width="60"/>  
  16.                         StackPanel>  
  17.                     DataTemplate>  
  18.                 Setter.Value>  
  19.             Setter>  
  20.               
  21.             <Style.Triggers>  
  22.                 <MultiDataTrigger>  
  23.                     <MultiDataTrigger.Conditions>  
  24.                         <Condition Binding="{Binding Path=ID}" Value="2"/>  
  25.                         <Condition Binding="{Binding Path=Name}" Value="Tom"/>  
  26.                     MultiDataTrigger.Conditions>  
  27.                     <MultiDataTrigger.Setters>  
  28.                         <Setter Property="Background" Value="Orange"/>  
  29.                     MultiDataTrigger.Setters>  
  30.                 MultiDataTrigger>  
  31.             Style.Triggers>  
  32.         Style>  
  33.     Window.Resources>  
  34.       
  35.     <StackPanel>  
  36.         <ListBox x:Name="listBoxStudent" Margin="5"/>  
  37.     StackPanel>  
  38. Window>
后台代码:
  1. ///   
  2. /// MainWindow.xaml 的交互逻辑  
  3. ///   
  4. public partial class MainWindow : Window  
  5. {  
  6.     public MainWindow()  
  7.     {  
  8.         InitializeComponent();  
  9.   
  10.         List stuList = new List(){  
  11.             new Student(){ID="1",Name="Peter",Age=25},  
  12.             new Student(){ID="2",Name="Tom",Age=27},  
  13.             new Student(){ID="3",Name="Ben",Age=20}  
  14.         };  
  15.   
  16.         this.listBoxStudent.ItemsSource = stuList;  
  17.     }  
  18.   
  19. }  
  20.   
  21. ///   
  22. /// 学生类  
  23. ///   
  24. public class Student{  
  25.     public string ID{get;set;}  
  26.     public string Name { getset; }  
  27.     public int Age { getset; }  
  28. }  

你可能感兴趣的:(C#)