目录

WPF-Behavior 之 EventToCommand

将事件转换为命令 (EventToCommand),用来把 UI 事件(如 Click、Loaded、SelectionChanged等)绑定到 ViewModel 的 ICommand,从而避免 code-behind 里写事件处理逻辑。

一、EventCommand 是什么

它属于 Microsoft.Xaml.Behaviors.Wpf 或 Pism 的 Prism.Interactivity

作用:把 XAML 中的事件转换为 ICommand 调用

<Button Click="Button_Click"/>

变为:

<Button>
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="Click">
      <i:InvokeCommandAction Command="{Binding SaveCommand}"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</Button>

二、常见写法

1.安装包

Microsoft.Xaml.Behaviors.Wpf

2.引用命名空间

xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

3.绑定事件到命令

<Button Content="保存">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <i:InvokeCommandAction Command="{Binding SaveCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>
public ICommand SaveCommand => new RelayCommand(() =>
{
    // 保存逻辑
});

三、传递事件参数

传事件对象本身

<i:InvokeCommandAction Command="{Binding SelectionChangedCommand}"
                       PassEventArgsToCommand="True"/>
public ICommand SelectionChangedCommand => new RelayCommand<SelectionChangedEventArgs>(args =>
{
    var item = args.AddedItems[0];
});

传绑定参数(CommandParameter)

<i:InvokeCommandAction Command="{Binding DeleteCommand}"
                       CommandParameter="{Binding SelectedItem, ElementName=listBox}" />

传控件本身(RelativeSource)

<i:InvokeCommandAction Command="{Binding LoadedCommand}"
                       CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}" />

四、Prism 的 EventToCommand

xmlns:prism="http://prismlibrary.com/"
<Button Content="保存"
        prism:Click.Command="{Binding SaveCommand}" />
<i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
        <prism:InvokeCommandAction Command="{Binding SelectionChangedCommand}"
                                   CommandParameter="{Binding SelectedItem, ElementName=list}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

五、复杂控件中的使用

DataGrid RowDoubleClick → Command

<DataGrid>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseDoubleClick">
            <i:InvokeCommandAction Command="{Binding DataContext.RowDoubleClickCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
                                   CommandParameter="{Binding}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</DataGrid>

六、自己实现 EventToCommand

如果需要对事件过滤、节流、防抖等:

public class EventToCommandBehavior : TriggerAction<DependencyObject>
{
    public ICommand Command { get; set; }

    protected override void Invoke(object parameter)
    {
        if (Command?.CanExecute(parameter) == true)
            Command.Execute(parameter);
    }
}