前言
在wpf中 Interaction.Triggers是对命令的补充,命令能应用的场合有限,比如Button的单击事件,但是像window窗体的Loaded事件,TextBox的TextChanged就无法使用命令。Interaction.Triggers的结构如下:
csharp
<控件>
<i:Interaction.Triggers>
<触发器类型>
<动作类型 属性="值"/>
</触发器类型>
</i:Interaction.Triggers>
</控件>
1、引用dll
在NuGet包管理器中选择Microsoft.Xaml.Behaviors.Wpf这个包安装
2、引用命名空间
在xaml代码中加上如下代码
csharp
xmlns:Event="http://schemas.microsoft.com/xaml/behaviors"
3、window的Loaded事件
下面的代码中EventName指定了需要绑定的事件的名称,这里是"Loaded"事件。在InvokeCommandAction的Command属性中绑定事件CommandWindowLoaded,这里的CommandWindowLoaded在ViewModel类中定义和实例化。
csharp
<Window x:Class="wpf之Interaction.Triggers.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:wpf之Interaction.Triggers"
xmlns:Event="http://schemas.microsoft.com/xaml/behaviors"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Event:Interaction.Triggers>
<Event:EventTrigger EventName="Loaded">
<Event:InvokeCommandAction Command="{Binding CommandWindowLoaded}"/>
</Event:EventTrigger>
</Event:Interaction.Triggers>
<Grid>
</Grid>
</Window>
自定义命令DelegateCommand
csharp
public class DelegateCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Func<object, bool> _canExecute;
public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
if (_canExecute != null)
{
return _canExecute(parameter);
}
else
{
return true;
}
}
public void Execute(object parameter)
{
_execute(parameter);
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
}
定义ViewMode的基类ViewModelBase
csharp
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propname)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propname));
}
}
}
定义ViewMode并且继承ViewModelBase,在ViewMode中实例化一个命令,
csharp
public class ViewModel : ViewModelBase
{
public ICommand CommandWindowLoaded { get; set; }
public ViewModel()
{
CommandWindowLoaded = new DelegateCommand(WindowLoaded);
}
public void WindowLoaded(object param)
{
Console.WriteLine("窗体加载");
}
}
4、TextBox的TextChanged事件
当你改变TextBox内容的时候,不停的就会触发TextChangedCommand命令执行。
下面的代码同样是通过EventName指定需要绑定的事件类型,通过Command属性来绑定ViewModel中具体的事件,同时还可以传递参数。
csharp
<Window x:Class="wpf之Interaction.Triggers.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:wpf之Interaction.Triggers"
xmlns:Event="http://schemas.microsoft.com/xaml/behaviors"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Event:Interaction.Triggers>
<Event:EventTrigger EventName="Loaded">
<Event:InvokeCommandAction Command="{Binding CommandWindowLoaded}"/>
</Event:EventTrigger>
</Event:Interaction.Triggers>
<Grid>
<StackPanel >
<TextBox x:Name="tbx_test" Height="20" Width=" 40">
<Event:Interaction.Triggers>
<Event:EventTrigger EventName="TextChanged">
<Event:InvokeCommandAction Command="{Binding TextChangedCommand}" CommandParameter="{Binding Path=Text,ElementName=tbx_test}"/>
</Event:EventTrigger>
</Event:Interaction.Triggers>
</TextBox >
</StackPanel >
</Grid>
</Window>
csharp
public class ViewModel : ViewModelBase
{
public ICommand CommandWindowLoaded { get; set; }
public ICommand TextChangedCommand { get; set; }
public ViewModel()
{
CommandWindowLoaded = new DelegateCommand(WindowLoaded);
TextChangedCommand= new DelegateCommand(TextChange);
}
public void WindowLoaded(object param)
{
Console.WriteLine("窗体加载");
}
public void TextChange(object param)
{
Console.WriteLine($"文本修改{param}");
}
}