样式(Style):

WPF样式概述:

什么是样式?样式有什么作用?首先,WPF框架提供了许许多多的控件,而这些控件拥有不同的属性,例如一个button控件的长宽、背景颜色、字体字号、内外边距、边框等,我们可以设置这些属性的值,从而让控件呈现出不同的显示效果。如果有多个button,我们该怎么办呢,每个按钮都去设置一遍属性?显示这是不科学的。于是,我们可以将一系列的属性的设置“集中”起来,将它们定义成一个样式,最后将这个样式再设置到控件上,从而达到“一处定义多处引用”的偷懒行为。

样式——就是一种将一组属性值应用到多个元素的便捷方法。

样式写在Source中且只能定义依赖属性(Property):

<Application.Resources>

<Style x:Key="ButtonStyle" TargetType="Button">

<Setter Property="Width" Value="100"/>

<Setter Property="Height" Value="30"/>

<Setter Property="Background" Value="Red"/>

</Style>

</Application.Resources>

//应用

<Button Content="新增人员" Click="Button_Click_1" Style="{StaticResource ButtonStyle}"/>

注意:在引用样式时,我们有两种方式,分别是DynamicResource和StaticResource,后面再写上样式的名称。DynamicResource表示动态资源,StaticResource表示静态资源。这两者的区别是:静态资源在第一次编译后即确定其对象或值,之后不能对其进行修改。动态资源则是在运行时决定,当运行过程中真正需要时,才到资源目标中查找其值。因此,我们可以动态地修改它。由于动态资源的运行时才能确定其值,因此效率比静态资源要低。

Resource资源:

WPF中的资源是指可以在应用中的不同位置重复使用的对象。而拥有这些对象的文件,我们可称为资源文件。这些资源文件可以编译到程序集中,可使用包 URI 来引用一组特殊的 WPF 应用程序代码文件,包括窗口、页面、流文档和资源字典。 例如,可以将Application.StartupUri 属性设置为包 URI,用于引用要在应用程序启动时加载的窗口或页面。

<Application x:Class="HelloWorld.App"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="clr-namespace:HelloWorld"

StartupUri="MainWindow.xaml">

<Application.Resources>

</Application.Resources>

</Application>

在App.xaml文件中,通常默认的StartupUri属性值为MainWindow.xaml,这个MainWindow.xaml文件实际上就是一个资源文件,它包含了主窗体界面的所有XAML代码。

我们可以在XAML中删除StartupUri属性的设置,在Application的后端C#代码中去引用主窗体的资源文件。

public partial class App : Application

{

protected override void OnStartup(StartupEventArgs e)

{

base.OnStartup(e);

Uri uri = new Uri("MainWindow.xaml", UriKind.Relative);

base.StartupUri = uri;

}

}

如上所示,我们重写了OnStartup方法成员,利用Uri包引入MainWindow.xaml,并设置到StartupUri属性,F5运行,同样会启动主窗体。

资源是以字典的形式存在于程序中——也就是ResourceDictionary(资源字典)。其次,它们通常保存在Resources属性中。哪些类型有Resources属性?

答案是:Application类、FrameworkElement基类和FrameworkContentElement基类。

ResourceDictionary资源字典:

在项目中新建一个Style文件夹,右键-添加-资源字典文件。创建一个Button.xaml的资源文件,并在其中写下内容。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<Style x:Key="BlueButtonStyle" TargetType="Button">

<Setter Property="Width" Value="100"/>

<Setter Property="Height" Value="30"/>

<Setter Property="Background" Value="Blue"/>

<Setter Property="Foreground" Value="White"/>

<Setter Property="Margin" Value="3"/>

</Style>

</ResourceDictionary>

回到项目的App.xaml文件中,编写如下内容

<Application.Resources>

<ResourceDictionary>

<SolidColorBrush x:Key="ButtonBackground" Color="Red"/>

<SolidColorBrush x:Key="ButtonForeground" Color="White"/>

<Style x:Key="ButtonStyle" TargetType="Button">

<Setter Property="Width" Value="100"/>

<Setter Property="Height" Value="30"/>

<Setter Property="Background" Value="{StaticResource ButtonBackground}"/>

<Setter Property="Foreground" Value="{StaticResource ButtonForeground}"/>

<Setter Property="Margin" Value="3"/>

</Style>

<ResourceDictionary.MergedDictionaries>

<ResourceDictionary Source="Style/Button.xaml"/> //集合形式

</ResourceDictionary.MergedDictionaries>

</ResourceDictionary>

</Application.Resources>

Trigger触发器:

触发器是指当满足预设的条件时去执行一些事务的工具,比如我们希望鼠标移到某个按钮上方时,这个按钮的颜色、大小发生一些改变。这个时候,条件是鼠标移到按钮上,执行的事务是改变按钮的颜色和大小。

示例:

<Style x:Key="GreenButtonStyle" TargetType="Button">

<Setter Property="Width" Value="100"/>

<Setter Property="Height" Value="30"/>

<Setter Property="Background" Value="Green"/>

<Setter Property="Foreground" Value="White"/>

<Setter Property="Margin" Value="3"/>

<Style.Triggers>

<Trigger Property="IsMouseOver" Value="True">

<Setter Property="Foreground" Value="Red"/>

<Setter Property="Width" Value="150"/>

<Setter Property="Height" Value="50"/>

<Setter Property="Content" Value="鼠标移入"/>

</Trigger>

</Style.Triggers>

</Style>

MultiTrigger多条件触发器:

MultiTrigger表示多个条件同时满足时才会触发的触发器。

属性成员:

Conditions属性:MultiTrigger的Conditions属性是一个集合,表示条件。这个集合的元素是Condition类型。

Setters属性:MultiTrigger的Setters属性也是一个集合,表示触发器触发后要设置的项。

示例:

<CheckBox x:Name="checkbox">

<CheckBox.Style>

<Style TargetType="CheckBox">

<Setter Property="Content" Value="MultiTrigger"/>

<Setter Property="Width" Value="150"/>

<Setter Property="Height" Value="30"/>

<Setter Property="Background" Value="Orange"/>

<Setter Property="Foreground" Value="Green"/>

<Setter Property="Margin" Value="3"/>

<Style.Triggers>

<MultiTrigger>

<MultiTrigger.Conditions>

<Condition Property="IsMouseOver" Value="True"/>

<Condition Property="IsChecked" Value="True"/>

</MultiTrigger.Conditions>

<MultiTrigger.Setters>

<Setter Property="Foreground" Value="Red"/>

<Setter Property="Content" Value="多条件触发器"/>

</MultiTrigger.Setters>

</MultiTrigger>

</Style.Triggers>

</Style>

</CheckBox.Style>

</CheckBox>

DataTrigger数据触发器:

它会在绑定数据满足指定条件时应用属性值或执行操作。

DataTrigger拥有一个Binding属性,表明它可以绑定某个控件的属性,或者是某个ViewModel的属性,Value属性则是表示绑定的属性达到某个值时,触发条件成立,然后去执行Setters集合里面的内容。

示例:

<DataGrid ItemsSource="{Binding Persons}" SelectedItem="{Binding Person}" AutoGenerateColumns="False">

<DataGrid.RowStyle>

<Style TargetType="DataGridRow">

<Style.Triggers>

<DataTrigger Binding="{Binding Age}" Value="19">

<Setter Property="Background" Value="LightBlue"/>

</DataTrigger>

<DataTrigger Binding="{Binding Age}" Value="20">

<Setter Property="Background" Value="LightGreen"/>

</DataTrigger>

<DataTrigger Binding="{Binding Age}" Value="21">

<Setter Property="Background" Value="LightCoral"/>

</DataTrigger>

<DataTrigger Binding="{Binding ElementName=_CheckBox,Path=IsChecked}" Value="True">

<Setter Property="Foreground" Value="Red"/>

<Setter Property="FontSize" Value="16"/>

<Setter Property="FontWeight" Value="Bold"/>

</DataTrigger>

</Style.Triggers>

</Style>

</DataGrid.RowStyle>

<DataGrid.Columns>

<DataGridTextColumn Header="姓名" Binding="{Binding Name}"/>

<DataGridTextColumn Header="年龄" Binding="{Binding Age}"/>

<DataGridTextColumn Header="生日" Binding="{Binding Address}"/>

</DataGrid.Columns>

</DataGrid>

MultiDataTrigger多数据触发器:

示例:

<MultiDataTrigger>

<MultiDataTrigger.Conditions>

<Condition Binding="{Binding Path=Age}" Value="20"/>

<Condition Binding="{Binding Path=Name}" Value="张三"/>

</MultiDataTrigger.Conditions>

<MultiDataTrigger.Setters>

<Setter Property="Foreground" Value="Red"/>

<Setter Property="FontSize" Value="16"/>

<Setter Property="FontWeight" Value="Bold"/>

</MultiDataTrigger.Setters>

</MultiDataTrigger>

EventTrigger事件触发器:

EventTrigger,表示某个事件发生时,执行某一组操作,而这一组操作,通常是对当前控件或其它控件的属性做一些改变。

RoutedEvent :表示一个事件,用来激活当前触发器。

SourceName:表示一个控件的名称,即是哪个控件的事件发生后,去激活事件触发器。

Actions :获取事件发生时要应用的操作的集合。这个集合的元素只能是BeginStoryboard,表示开始一个故事板,故事板里面将会执行一个动画。

<Window.Resources>

<Storyboard x:Key="OnChecked">

<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="_LeftBorder">

<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>

</DoubleAnimationUsingKeyFrames>

</Storyboard>

<Storyboard x:Key="OnUnchecked">

<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="_LeftBorder">

<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="200"/>

</DoubleAnimationUsingKeyFrames>

</Storyboard>

</Window.Resources>

<Window.Triggers>

<EventTrigger RoutedEvent="ToggleButton.Checked" SourceName="_CheckBox">

<BeginStoryboard Storyboard="{StaticResource OnChecked}"/>

</EventTrigger>

<EventTrigger RoutedEvent="ToggleButton.Unchecked" SourceName="_CheckBox">

<BeginStoryboard Storyboard="{StaticResource OnUnchecked}"/>

</EventTrigger>

</Window.Triggers>

<Grid>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="auto"/>

<ColumnDefinition/>

</Grid.ColumnDefinitions>

<Border Grid.Column="0" x:Name="_LeftBorder" Width="188" Background="LightCyan">

<TextBlock Text="菜单区域" HorizontalAlignment="Center" VerticalAlignment="Center"/>

</Border>

<Border Grid.Column="1" x:Name="_RightBorder" >

<CheckBox x:Name="_CheckBox">

<CheckBox.Style>

<Style TargetType="CheckBox">

<Setter Property="Width" Value="50"/>

<Setter Property="Height" Value="50"/>

<Setter Property="Content" Value="开"/>

<Setter Property="Background" Value="LightGreen"/>

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="CheckBox">

<Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" CornerRadius="60" Background="{TemplateBinding Background}">

<TextBlock Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/>

</Border>

</ControlTemplate>

</Setter.Value>

</Setter>

<Style.Triggers>

<Trigger Property="IsChecked" Value="True">

<Setter Property="Background" Value="Red"/>

<Setter Property="Foreground" Value="White"/>

<Setter Property="Content" Value="关"/>

</Trigger>

<EventTrigger RoutedEvent="MouseEnter">

<EventTrigger.Actions>

<BeginStoryboard>

<Storyboard>

<DoubleAnimation Duration="0:0:0.300" Storyboard.TargetProperty="Width" To="60" />

<DoubleAnimation Duration="0:0:0.300" Storyboard.TargetProperty="Height" To="60" />

</Storyboard>

</BeginStoryboard>

</EventTrigger.Actions>

</EventTrigger>

<EventTrigger RoutedEvent="MouseLeave">

<EventTrigger.Actions>

<BeginStoryboard>

<Storyboard>

<DoubleAnimation Duration="0:0:0.300" Storyboard.TargetProperty="Width" To="50" />

<DoubleAnimation Duration="0:0:0.300" Storyboard.TargetProperty="Height" To="50" />

</Storyboard>

</BeginStoryboard>

</EventTrigger.Actions>

</EventTrigger>

</Style.Triggers>

</Style>

</CheckBox.Style>

</CheckBox>

</Border>

</Grid>