【发布时间】:2015-11-24 20:37:38
【问题描述】:
问题:我想通过 XAML 将事件绑定到 ViewModel 的公共方法。
臭名昭著的解决方案是在ViewModel 上创建一个公共ICommand 属性,该属性返回RelayCommand 或DelegateCommand,然后在XAML 中使用Windows.Interactivity 中的EventTrigger 和InvokeCommandAction 进行绑定事件到命令。非常相似的替代方法是使用 MVVMLight 的EventToCommand,它甚至提供了将EventArgs 作为命令参数传递的可能性。
这种解决方案存在过于冗长的缺陷,因此使代码难以重构和维护。
我想使用 MarkupExtension 将事件绑定到 ViewModel 的公共方法直接。来自this blog post 的EventBindingExtension 提供了这种可能性。
XAML 中的示例用法:
<Button Content="Click me" Click="{my:EventBinding OnClick}" />
其中ViewModel有如下方法:
public void OnClick(object sender, EventArgs e)
{
MessageBox.Show("Hello world!");
}
我对这种方法有几个问题:
- 我已经对其进行了测试,它对我来说就像一个魅力,但由于我不是专家,我想问一下这个解决方案是否存在一些缺陷或可能的意外行为。
- 这是否符合 MVVM 模式?
-
EventBindingExtension需要它绑定的公共方法来匹配事件的参数。如何扩展它以允许省略object source参数? - 在 WPF 或 NuGet 包的框架中还有哪些其他类似的 MarkupExtensions 可用?
【问题讨论】:
-
纯粹出于好奇,为什么必须使用事件?由于它在 ViewModel 中,它显然不处理 UI 更新等,所以我想知道在这种情况下一个事件有什么命令没有。
-
@Kilazur 首先,有很多事件没有对应的命令,例如
ListViewItem类根本没有命令,所以如果你想处理MouseDoubleClick事件,这是唯一的机会。其次,即使对于确实有对应命令的Button的Click事件,这种方法对我来说似乎更简洁,因为样板代码几乎为零(与使用命令时的大量样板代码相反)。