WPF中行为与触发器的概念及用法
完全来源于十月的寒流,感谢大佬讲解
一、行为 (Behaviors)
behaviors的简单测试
<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测试
<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>
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()
{
}
}
}
点击按钮后清空某个文本框的内容
<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>
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();
}
}
}
用鼠标滚轮调整文本框中的数字
<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>
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)
示例代码
<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>
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 变成红色
<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>