样式(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">
<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>
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">
<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>
</Border>
</Grid>