吉吉于

WPF Study notes(2):Setter and Trigger in Style

This article is about Style in WPF.

As the CSS in HTML,Style controlls static appearance and behavior of our WPF applications.

Two of the most important elements in Style are Setter and Trigger.

There are five kinds of Trigger,I’ll show you two of them first. Basic Trigger and MultiTrigger.

Well,Let us see how it works.

Demo:

XAML:

<Window
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	x:Class="Lazy_Setter_Trigger.MainWindow"
	x:Name="Window"
	Title="Hello WPF!"
	Width="640" Height="480">
	<Window.Resources>
		<Style TargetType="TextBlock">
			<Style.Setters>
				<Setter Property="FontSize" Value="40"/>
				<Setter Property="TextDecorations" Value="Underline"/>
				<Setter Property="FontStyle" Value="Italic"/>
			</Style.Setters>
		</Style>
		<Style TargetType="CheckBox">
			<Style.Triggers>
				<Trigger Property="IsChecked" Value="true">
					<Trigger.Setters><!--此标签可以省略-->
						<Setter Property="FontSize" Value="20"/>
						<Setter Property="Foreground" Value="Orange"/>
					</Trigger.Setters>
				</Trigger>
				<MultiTrigger><!--MultiTrigger,必须同时多个条件同时成立才会被出发-->
					<MultiTrigger.Conditions>
						<Condition Property="IsChecked" Value="true"/>
						<Condition Property="Content" Value="Twenty Years"/>
					</MultiTrigger.Conditions>
					<MultiTrigger.Setters>
						<Setter Property="FontSize" Value="30"/>
						<Setter Property="Foreground" Value="#FFFF4040"/>
					</MultiTrigger.Setters>
				</MultiTrigger>
			</Style.Triggers>
		</Style>
	</Window.Resources>
	<StackPanel Margin="5">
		<TextBlock Text="Hello WPF!"/>
		<TextBlock Text="This is a sample for Style."/>
		<TextBlock Text="by Lazynight 2012.4.3" Style="{x:Null}"/>
		<Line Margin="0 10 0 10" Stroke="Black" X1="0" Y1="0" X2="640" Y2="0" Stretch="Fill"/>
		<CheckBox Content="Lazynight" Margin="5"/>
		<CheckBox Content="Flowerowl" Margin="10 20 300 5"/><!--Maring 和CSS的方向顺序不一样,此处Margin顺序为:左,上,右,下-->
		<CheckBox Content="NightDivides" Margin="5"/>
		<CheckBox Content="Twenty Years" />
	</StackPanel>
</Window>

We know that WPF is driven by data, different from those languages driven by event.
OK,there are still three triggers: DataTrigger,MultiDataTrigger,EventTrigger,I’ll show you one by one.

1.DataTrigger Demo:

When textBox’s length is greater than 6 , it’s border will be changed.

XAML:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Lazy_Setter_Trigger"
    x:Class="Lazy_Setter_Trigger.MainWindow"
	Title="Hello WPF!"
	x:Name="Window"
	Width="640" Height="480">
    <Window.Resources>
        <local:L2BConvert x:Key="cvtr"/>
        <Style TargetType="TextBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self},Path=Text.Length,Converter={StaticResource cvtr}}" Value="true">
                    <Setter Property="BorderBrush" Value="#ff4040"/>
                    <Setter Property="BorderThickness" Value="3" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel>
        <TextBox Margin="5" />
        <TextBox Margin="5" />
        <TextBox Margin="5"/>
    </StackPanel>
</Window>

CS:

public class L2BConvert:IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int textLength = (int)value;
            return textLength > 6 ? true : false;
        }
        public object ConvertBack(object value,Type targetType,object parameter,CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

2.MultiDataTrigger Demo:

XAML:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="Lazy_Setter_Trigger.MainWindow"
        Title="MultiDataTrigger" Width="400" Height="300">
    <Window.Resources>
        <Style TargetType="ListBoxItem">
            <!--使用Style设置DataTemplate-->
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding ID}" Width="60"/>
                            <TextBlock Text="{Binding Age}" Width="60"/>
                            <TextBlock Text="{Binding Name}" Width="120"/>
                        </StackPanel>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
            <!--MultiDataTrigger-->
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=ID}" Value="100"/>
                        <Condition Binding="{Binding Path=Name}" Value="Lazynight"/>
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.Setters>
                        <Setter Property="Background" Value="#000" />
                        <Setter Property="Foreground" Value="#fff"/>
                    </MultiDataTrigger.Setters>
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel>
        <ListBox x:Name="listBoxStudent" Margin="5"/>
    </StackPanel>
</Window>

CS:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Globalization;

namespace Lazy_Setter_Trigger
{
	public partial class MainWindow : Window
	{
		public MainWindow()
		{
			this.InitializeComponent();
            List<Student> student = new List<Student>()
            {
                new Student(100,20,"Lazynight"),
                new Student(101,19,"Flowerowl"),
                new Student(102,18,"Sinking Ship"),
                new Student(103,17,"Frozen World"),
                new Student(104,21,"Dead Meat")
            };
            this.listBoxStudent.ItemsSource = student;
		}
	}

    public class Student
    {
        public int ID { get; set; }
        public int Age { get; set; }
        public string Name { get; set; }
        public Student(int id,int age,string name)
        {
            ID = id;
            Age = age;
            Name = name;
        }
    }
}

3.EventTrigger

This is the most special one.It’s not driven by data neither the property ,it’s driven by event.

And ,after being triggered,it’s not use “Setter” ,but to run a period of animation。

So,the animation of UI is always connected to EventTrigger.

Demo:

XAML:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="Lazy_Setter_Trigger.MainWindow"
        Title="EventTrigger" Width="400" Height="300">
    <Window.Resources>
        <Style TargetType="Button">
            <Style.Triggers>
                <!--鼠标进入-->
                <EventTrigger RoutedEvent="MouseEnter">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation To="150" Duration="0:0:0.2" Storyboard.TargetProperty="Width"/>
                            <DoubleAnimation To="150" Duration="0:0:0.2" Storyboard.TargetProperty="Height"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <!--鼠标离开-->
                <EventTrigger RoutedEvent="MouseLeave">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Width"/>
                            <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Height"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Canvas>
        <Button Width="40" Height="40" Content="GO!"/>
    </Canvas>
</Window>

PS:用鸟语写不是为了装13,只是为了提高鸟语水平,以便以后做个鸟人,方便看鸟书。
Download

转载请注明:于哲的博客 » WPF Study notes(2):Setter and Trigger in Style