WPF中行为与触发器的概念及用法

完全来源于十月的寒流,感谢大佬讲解

一、行为 (Behaviors)


behaviors的简单测试

csharp 复制代码
<Window x:Class="Test_05.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Test_05"
        mc:Ignorable="d"
        xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Border x:Name="bord" Width="50" Height="50" Background="Blue">
            <b:Interaction.Behaviors>
                <b:MouseDragElementBehavior></b:MouseDragElementBehavior>
            </b:Interaction.Behaviors>
        </Border>
    </Grid>
</Window>

自定义behaviors测试

csharp 复制代码
<Window x:Class="Test_05.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Test_05"
        mc:Ignorable="d"
        xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Border x:Name="bord" Width="50" Height="50" Background="Blue" RenderTransformOrigin="1.47,0.858">
            <b:Interaction.Behaviors>
                <b:MouseDragElementBehavior></b:MouseDragElementBehavior>
                <local:MyBehaviors></local:MyBehaviors>
            </b:Interaction.Behaviors>
        </Border>
    </Grid>
</Window>
csharp 复制代码
using Microsoft.Xaml.Behaviors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Navigation;
using System.Windows.Shapes;

namespace Test_05
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class MyBehaviors : Behavior<Border>
    {
        protected override void OnAttached()
        {
            //AssociatedObject.Background = Brushes.Green;
            AssociatedObject.MouseEnter += (sender,args) => 
            {
                AssociatedObject.Background = Brushes.Green;
            };
            AssociatedObject.MouseLeave += (sender, args) =>
            {
                AssociatedObject.Background = Brushes.Blue;
            };
        }

        protected override void OnDetaching()
        {
        }
    }
}

点击按钮后清空某个文本框的内容

csharp 复制代码
<Window x:Class="Test_05.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Test_05"
        mc:Ignorable="d"
        xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <TextBox x:Name="tbox"></TextBox>
        <Button HorizontalAlignment="Left" Content="clear">
            <b:Interaction.Behaviors>
                <local:ClearTextBox Target="{Binding ElementName=tbox}"></local:ClearTextBox>
            </b:Interaction.Behaviors>
        </Button>
    </StackPanel>
</Window>
csharp 复制代码
using Microsoft.Xaml.Behaviors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Navigation;
using System.Windows.Shapes;

namespace Test_05
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class ClearTextBox : Behavior<Button>
    {
        public TextBox Target
        {
            get { return (TextBox)GetValue(TargetProperty); }
            set { SetValue(TargetProperty, value); }
        }

        public static readonly DependencyProperty TargetProperty =
            DependencyProperty.Register("Target", typeof(TextBox), typeof(ClearTextBox), new PropertyMetadata(null));

        protected override void OnAttached()
        {
            AssociatedObject.Click += EmptyText;
        }

        private void EmptyText(object sender, RoutedEventArgs e)
        {
            Target?.Clear();
        }
    }
}

用鼠标滚轮调整文本框中的数字

csharp 复制代码
<Window x:Class="Test_05.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Test_05"
        mc:Ignorable="d"
        xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <TextBox x:Name="tbox" FontSize="30" Text="0">
            <b:Interaction.Behaviors>
                <local:MouseWheelBehavior MinValue="-100" MaxValue="100" Scale="3"></local:MouseWheelBehavior>
            </b:Interaction.Behaviors>
        </TextBox>
    </StackPanel>
</Window>
csharp 复制代码
using Microsoft.Xaml.Behaviors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Navigation;
using System.Windows.Shapes;

namespace Test_05
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class MouseWheelBehavior : Behavior<TextBox>
    {
        public int MaxValue { get; set; } = 10;
        public int MinValue { get; set; } = -10;
        public int Scale { get; set; } = 1;

        protected override void OnAttached()
        {
            AssociatedObject.MouseWheel += Wheel;
        }

        private void Wheel(object sender, MouseWheelEventArgs e)
        {
            int num = int.Parse(AssociatedObject.Text);

            if (e.Delta > 0)
            {
                num += Scale;
            }
            else
            {
                num -= Scale;
            }
            if (num > MaxValue)
            {
                num = MaxValue;
            }
            if (num < MinValue)
            {
                num = MinValue;
            }
            AssociatedObject.Text = num.ToString();
        }
    }
}

二、触发器 (Triggers)


示例代码

csharp 复制代码
<Window x:Class="Test_05.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Test_05"
        mc:Ignorable="d"
        xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainWindowViewModel></local:MainWindowViewModel>
    </Window.DataContext>
    
    <b:Interaction.Triggers>
        <b:EventTrigger EventName="Loaded">
            <b:InvokeCommandAction Command="{Binding LoadedCommand}"></b:InvokeCommandAction>
        </b:EventTrigger>
    </b:Interaction.Triggers>
    <StackPanel>
        <TextBox Name="tbox" Text="{Binding Text}" FontSize="30"></TextBox>
        <Button HorizontalAlignment="Left" Content="Close" FontSize="30">
            <b:Interaction.Triggers>
                <b:EventTrigger EventName="Click">
                    <b:CallMethodAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window}}" MethodName="Close"></b:CallMethodAction>
                    <!--<b:CallMethodAction TargetObject="{Binding Source={x:Static Application.Current}}" MethodName="ShutDown"></b:CallMethodAction>-->
                </b:EventTrigger>
            </b:Interaction.Triggers>
        </Button>
    </StackPanel>
</Window>
csharp 复制代码
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Xaml.Behaviors;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Navigation;
using System.Windows.Shapes;

namespace Test_05
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class MainWindowViewModel : ObservableObject
    {
        string text;
        public string Text
        {
            get => text; 
            set => SetProperty(ref text, value);
        }

        public AsyncRelayCommand LoadedCommand { get; }

        public MainWindowViewModel()
        {
            LoadedCommand = new AsyncRelayCommand(Loaded);
        }

        private async Task Loaded()
        {
            await Task.Delay(2000);
            Text = "Hello World";
        }
    }
}

Button IsMouseOver 变成红色

csharp 复制代码
<Window x:Class="Test_05.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Test_05"
        mc:Ignorable="d"
        xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainWindowViewModel></local:MainWindowViewModel>
    </Window.DataContext>
    
    <b:Interaction.Triggers>
        <b:EventTrigger EventName="Loaded">
            <b:InvokeCommandAction Command="{Binding LoadedCommand}"></b:InvokeCommandAction>
        </b:EventTrigger>
    </b:Interaction.Triggers>
    <StackPanel>
        <TextBox Name="tbox" Text="{Binding Text}" FontSize="30"></TextBox>
        <Button HorizontalAlignment="Left" Content="Close" FontSize="30" Padding="10">
            <!--<Button.Style>
                <Style TargetType="Button">
                    <Style.Triggers>
                        <DataTrigger Binding="{}"></DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>-->
            <b:Interaction.Triggers>
                <b:EventTrigger EventName="Click">
                    <!--<b:CallMethodAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window}}" MethodName="Close"></b:CallMethodAction>-->
                    <!--<b:CallMethodAction TargetObject="{Binding Source={x:Static Application.Current}}" MethodName="ShutDown"></b:CallMethodAction>-->
                </b:EventTrigger>
                <b:DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=IsMouseOver}" Value="True">
                    <b:ChangePropertyAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Button}}" PropertyName="Background" Value="Blue"></b:ChangePropertyAction>
                </b:DataTrigger>
            </b:Interaction.Triggers>
        </Button>
    </StackPanel>
</Window>
相关推荐
九鼎科技-Leo9 小时前
什么是 WPF 中的依赖属性?有什么作用?
windows·c#·.net·wpf
麻花201319 小时前
C#之WPF的C1FlexGrid空间的行加载事件和列事件变更处理动态加载的枚举值
开发语言·c#·wpf
lcintj19 小时前
【WPF】Prism学习(九)
学习·wpf·prism
界面开发小八哥19 小时前
界面控件DevExpress WPF中文教程:网格视图数据布局的列和卡片字段
wpf·界面控件·devexpress·ui开发·用户界面
△曉風殘月〆19 小时前
如何在WPF中嵌入其它程序
wpf
Crazy Struggle19 小时前
功能齐全的 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·跨平台·界面设计