【发布时间】:2012-12-16 20:46:45
【问题描述】:
如何通过按钮的特定事件(例如MouseDoubleClick)调用 ViewModel 上的命令?
【问题讨论】:
标签: wpf button mvvm command mouseevent
如何通过按钮的特定事件(例如MouseDoubleClick)调用 ViewModel 上的命令?
【问题讨论】:
标签: wpf button mvvm command mouseevent
您可以在 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 的乐趣,这是值得的。
【讨论】:
.Interactivity 命名空间不是 .NET Core。有人知道替代方案吗?
如果您要使用开箱即用的 WPF 中的命令和事件绑定,您需要自己做很多事情。仅使用已经提供命令甚至绑定的现有框架,例如 MVVM Light Toolkit 或 Cliburn Micro,您可以获得很多好处。
【讨论】: