WPF触发器与模板

触发器

触发器可以理解为,当达到了触发的条件,那么就执行预期内的响应,可以是样式、数据变化、动画等。触发器通过Style.Triggers集合连接到样式中,每个样式都可以有任意多个触发器,并且每个触发器都是System.Windows.TriggerBase的派生类实例,以下是触发器的类型:

  • Trigger:监测依赖属性的变化、触发器生效
  • MultiTrigger:通过多个条件的设置、达到满足条件、触发器生效
  • DataTrigger:通过数据的变化、触发器生效
  • MultiDataTrigger:多个数据条件的触发器
  • EventTrigger:事件触发器,触发了某类事件时,触发器生效

属性触发器

Trigger:监测依赖属性的变化、触发器生效

xaml 复制代码
<Window x:Class="EventLearn.UseStyle"
        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:EventLearn"
        mc:Ignorable="d"
        Title="UseStyle" Height="450" Width="800">

    <Window.Resources>
        <Style x:Key="BaseStyle" TargetType="Button">
            <Setter Property="Width" Value="100"/>
            <Setter Property="Height" Value="40"/>
            <Setter Property="Foreground" Value="Red"/>

            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Foreground" Value="Blue"/>
                    <Setter Property="FontSize" Value="20"/>
                </Trigger>
                
                <Trigger Property="IsMouseOver" Value="False">
                    <Setter Property="Foreground" Value="Red"/>
                    <Setter Property="FontSize" Value="15"/>
                </Trigger>                
            </Style.Triggers>
        </Style>
        
        <Style x:Key="style1" TargetType="Button" BasedOn="{StaticResource BaseStyle}">
            <Setter Property="Content" Value="Hello"/>
        </Style>
        
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Button Style="{StaticResource style1}" />
            <Button Style="{StaticResource style1}"/>
            <Button Style="{StaticResource style1}"/>
        </StackPanel>
    </Grid>
</Window>

Trigger类定义的属性

Tirgger属性 说明
Property Value 使用属性触发器,Property和Value属性用于指定触发器的激活时间。例如,Property = "IsMouseOver" ,Value = "True"
Setters 一旦激活触发器,就可以使用Setters定义一个Setter元素集合,来改变属性值。Setter类定义Property、TargetName和Value属性,已修改对象属性。
EnterActions ExitActions 除了定义 settm之 外,还可以定义 EnterActions 和 ExitActions。使用这两个属性,可以定义一个TriggerAction元素集合。EnterActions在启动触发器时激活(此时通过属性触发器应用Property/Value组合)。ExitActions在触发器结束之前激活(此时不再应用Property/Value组合)

多触发器

MultiTrigger:通过多个条件的设置、达到满足条件、触发器生效

MultiTrigger有一个Conditions属性,可以在其中设置属性的有效值。还有一个Setters属性,可以在其中指定需要设置的属性

xaml 复制代码
<Window
    x:Class="EventLearn.UseStyle"
    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:local="clr-namespace:EventLearn"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="UseStyle"
    Width="800"
    Height="450"
    mc:Ignorable="d">

    <Window.Resources>
        <Style x:Key="BaseStyle" TargetType="TextBox">
            <Setter Property="Width" Value="100" />
            <Setter Property="Height" Value="40" />
            <Setter Property="Foreground" Value="Red" />

            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Foreground" Value="Blue" />
                    <Setter Property="FontSize" Value="20" />
                </Trigger>

                <Trigger Property="IsMouseOver" Value="False">
                    <Setter Property="Foreground" Value="Red" />
                    <Setter Property="FontSize" Value="15" />
                </Trigger>

                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsMouseOver" Value="true"/>
                        <Condition Property="IsFocused" Value="true"/>
                    </MultiTrigger.Conditions>
                    <MultiTrigger.Setters>
                        <Setter Property="Background" Value="Pink"/>
                    </MultiTrigger.Setters>
                </MultiTrigger>
            </Style.Triggers>
        </Style>

        <Style x:Key="style1" TargetType="{x:Type TextBox}" BasedOn="{StaticResource BaseStyle}">
            
        </Style>

    </Window.Resources>
    <Grid>
        <StackPanel>
            <TextBox Style="{StaticResource style1}" />
            <TextBox Style="{StaticResource style1}" />
            <TextBox Style="{StaticResource style1}" />
        </StackPanel>
    </Grid>
</Window>

数据触发器

DataTrigger:通过数据的变化、触发器生效

xaml 复制代码
<Window
    x:Class="EventLearn.UseStyle"
    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:local="clr-namespace:EventLearn"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="UseStyle"
    Width="800"
    Height="450"
    mc:Ignorable="d">

    <Window.Resources>
        <Style x:Key="BaseStyle" TargetType="TextBox">
            <Setter Property="Width" Value="100" />
            <Setter Property="Height" Value="40" />
            <Setter Property="Foreground" Value="Red" />

            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Foreground" Value="Blue" />
                    <Setter Property="FontSize" Value="20" />
                </Trigger>

                <Trigger Property="IsMouseOver" Value="False">
                    <Setter Property="Foreground" Value="Red" />
                    <Setter Property="FontSize" Value="15" />
                </Trigger>

                <!--  当在TextBox中写入123时,背景颜色变绿  -->
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Text}" Value="123">
                    <Setter Property="Background" Value="SeaGreen" />
                </DataTrigger>
                
            </Style.Triggers>
        </Style>

        <Style
            x:Key="style1"
            BasedOn="{StaticResource BaseStyle}"
            TargetType="{x:Type TextBox}" />

    </Window.Resources>
    <Grid>
        <StackPanel>
            <TextBox Style="{StaticResource style1}" />
            <TextBox Style="{StaticResource style1}" />
            <TextBox Style="{StaticResource style1}" />
        </StackPanel>
    </Grid>
</Window>

模板

控件的外观及其功能在WPF中是完全分离的。虽然按钮有默认的外观,但可以用模板完全定制其外观。

WPF提供了几个模板类型,它们派生自基类FrameworkTemplate。

模板类型 说明
ControlTemplate 使用ControlTemplate可以指定控件的可视化结构,重新设计其外观
ItemsPanelTemplate 对于ItemsControl,可以赋予一个ItemsPanelTemplate,以指定其项的布局。每个ItemsControl都有一个默认的ItemsPanelTemplate。MenuItem使用WrapPanel,StatusBar使用DockPanel,ListBox使用VirtualizingStackPanel。
DataTemplate DataTemplates非常适用于对象的图形表示。给列表框指定样式,默认情况下,列表框中的项根据ToString()方法的输出来显示。应用DataTemplate,可以重写其操作,定义项的自定义表示
HierarchicalDataTemplate HierarchicalDataTemplate用于排列对象的树形结构。这个控件支持HierarchicalControls,如TreeViewItem和MenuItem

ControlTemplate

控件模板用来定义控件的外观、样式,还可通过控件模板的触发器(ControlTemplate.Triggers)修改控件的行为、响应动画等。

  • 对于WPF当中,每个控件都是无外观的,这意味着我们可以完全自定义其可视化的外观,但是不能修改其内部的行为,因为空间的行为已经被固定在控件的具体类中。
  • 在Winform当中,控件的外观与行为都被固定在空间的具体类中,当我们想要修改按钮的边框弧度或者修改控件身一些细节的时候,我们需要修改外观的同时,把原来具备的所有行为重写一遍,我们大多数称之为自定义控件。

ContentPresenter是控件内容的占位符,并定义了放置这些内容的位置。ContentPresenter的Content属性定义了内容的外观。

DataTemplate

xaml 复制代码
<Window
    x:Class="WpfApp1.MainWindow"
    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:local="clr-namespace:WpfApp1"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Grid>
        <ListBox ItemsSource="{Binding ElementName=com, Path=ItemsSource}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Name}" />
                        <TextBlock Text="---" />
                        <TextBlock Text="{Binding Sex}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <ComboBox
            x:Name="com"
            Width="100"
            Height="20">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Name}" />
                        <TextBlock Text="---" />
                        <TextBlock Text="{Binding Sex}" />
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </Grid>
</Window>
相关推荐
九鼎科技-Leo5 小时前
什么是 WPF 中的依赖属性?有什么作用?
windows·c#·.net·wpf
麻花201315 小时前
C#之WPF的C1FlexGrid空间的行加载事件和列事件变更处理动态加载的枚举值
开发语言·c#·wpf
lcintj15 小时前
【WPF】Prism学习(九)
学习·wpf·prism
界面开发小八哥15 小时前
界面控件DevExpress WPF中文教程:网格视图数据布局的列和卡片字段
wpf·界面控件·devexpress·ui开发·用户界面
△曉風殘月〆15 小时前
如何在WPF中嵌入其它程序
wpf
Crazy Struggle15 小时前
功能齐全的 WPF 自定义控件资源库(收藏版)
.net·wpf·ui控件库
shepherd枸杞泡茶1 天前
WPF动画
c#·.net·wpf
lcintj1 天前
【WPF】Prism学习(十)
学习·wpf·prism
wyh要好好学习1 天前
WPF数据加载时添加进度条
ui·wpf
code_shenbing1 天前
跨平台WPF框架Avalonia教程 三
前端·microsoft·ui·c#·wpf·跨平台·界面设计