【问题标题】:How to trigger ViewModel command for a specific button events如何触发特定按钮事件的 ViewModel 命令
【发布时间】:2012-12-16 20:46:45
【问题描述】:

如何通过按钮的特定事件(例如MouseDoubleClick)调用 ViewModel 上的命令?

【问题讨论】:

    标签: wpf button mvvm command mouseevent


    【解决方案1】:

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

    它是这样工作的:

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

    在 XAML 中,引用命名空间:

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

    然后在您的 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>
    

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

    备注

    为了阐明用法,这里有一个真实的例子,包括 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>
    

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

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

    【讨论】:

    • .NET 3.5 不支持,那么如何在没有 Prism 的 .NET 3.5 中做到这一点?
    • .Interactivity 命名空间不是 .NET Core。有人知道替代方案吗?
    【解决方案2】:
    【解决方案3】:

    如果您要使用开箱即用的 WPF 中的命令和事件绑定,您需要自己做很多事情。仅使用已经提供命令甚至绑定的现有框架,例如 MVVM Light ToolkitCliburn Micro,您可以获得很多好处。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-23
      • 1970-01-01
      • 2010-12-19
      • 1970-01-01
      • 1970-01-01
      • 2015-01-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多