wpf 如何为特定按钮事件触发 ViewModel 命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14122823/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:38:03  来源:igfitidea点击:

How to trigger ViewModel command for a specific button events

wpfbuttonmvvmcommandmouseevent

提问by Smaug

How can a command on a ViewModel be invoked by a specific event of a button, such as MouseDoubleClick?

ViewModel 上的命令如何被按钮的特定事件调用,例如MouseDoubleClick

回答by Marc

You can use the EventTriggerin the System.Windows.Interactivitynamespace, which is part of the so-called Prismframework. If you're just getting started with MVVM, don't care too much for Prism by now, but keep it in mind for later. Anyway, you can steel the EventTrigger

您可以EventTriggerSystem.Windows.Interactivity命名空间中使用 ,它是所谓的Prism框架的一部分。如果您刚刚开始使用 MVVM,现在不要太在意 Prism,但请记住它以备后用。无论如何,你可以钢EventTrigger

It works like this:

它是这样工作的:

Reference the assembly System.Windows.Interactivity.dll

引用程序集System.Windows.Interactivity.dll

In XAML, reference the namespace:

在 XAML 中,引用命名空间:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

Then in your Button or any other control, add a EventTrigger like this:

然后在您的 Button 或任何其他控件中,添加一个 EventTrigger,如下所示:

<Button Content="Button">
   <i:Interaction.Triggers>
      <i:EventTrigger EventName="MouseDoubleClick">
         <i:InvokeCommandAction Command="{Binding CommandToBindTo}" 
                                CommandParameter="{Binding CommandParameterToBindTo}" />
      </i:EventTrigger>
   </i:Interaction.Triggers>
</Button>

This way, you bind your event to a Commandon your DataContext.

这样,您将事件绑定到DataContext 上的命令

Remark

评论

To clarify the usage, here's a kind of real life example including the ViewModel. The fictional requirement is to allow the user to select an item in a list and then perform a command which takes the selected item as a parameter:

为了澄清用法,这里有一个现实生活中的例子,包括 ViewModel。虚构的需求是允许用户在列表中选择一个项目,然后执行一个将所选项目作为参数的命令:

<ListBox x:Name="ItemsList" ItemsSource="{Binding Items}" />

<Button Content="Do something with selected item">
   <i:Interaction.Triggers>
      <i:EventTrigger EventName="MouseDoubleClick">
         <i:InvokeCommandAction Command="{Binding DoSomethingCommand}" 
                                CommandParameter="{Binding SelectedItem, 
                                                   ElementName=ItemsList}" />
      </i:EventTrigger>
   </i:Interaction.Triggers>
</Button>

And that would be the ViewModel. Note how the parameter to the command is used, in the example with a generic version of a DelegateCommandobject as you get it in every MVVM framework (sometimes RelayCommand). This class takes the type of the required parameter as a generic parameter (here ItemViewModel) and requires a method which takes an according parameter (here ExecuteDoSomethingWithItem(ItemViewModel ...)). The rest is WPF magic: The oject to which the CommandParameterproperty is bound in your XAML will be passed through as the parameter in your Execute(...)function.

那将是 ViewModel。请注意命令的参数是如何使用的,在示例中使用DelegateCommand对象的通用版本,因为您在每个 MVVM 框架(有时RelayCommand)中获得它。此类将所需参数的类型作为泛型参数(此处ItemViewModel),并需要一个采用相应参数的方法(此处ExecuteDoSomethingWithItem(ItemViewModel ...))。其余的是 WPF 魔法:CommandParameter在 XAML 中绑定属性的对象将作为Execute(...)函数中的参数传递。

public class ViewModel
{
    ObservableCollection<ItemViewModel> Items { get; set; }

    public ICommand DoSomethingCommand
    {
        get
        {
            return _doSomethingCommand ??
                   (_doSomethingCommand = new DelegateCommand<ItemViewModel>(ExecuteDoSomethingWithItem));
        }
    }

    private DelegateCommand<ItemViewModel> _doSomethingCommand;

    private void ExecuteDoSomethingWithItem(ItemViewModel itemToDoSomethingWith)
    {
        // Do something
    }

    public ViewModel()
    {
        Items = new ObservableCollection<ItemViewModel>();
        // Fill the collection
    }
}

Have fun with learning MVVM, it's worth it.

享受学习 MVVM 的乐趣,值得。

回答by Vlad Bezden

You need to do a lot of pluming yourself if you going to use Command and Event Binding from out of the box WPF. You can gain a lot of just using existing framework such as MVVM Light Toolkit, or Cliburn Microthat already provide command and even binding.

如果您要使用开箱即用的 WPF 中的命令和事件绑定,您需要自己做很多事情。您可以通过使用现有框架(例如MVVM Light Toolkit或已经提供命令甚至绑定的Cliburn Micro)获得很多收益。