我想知道这是否会破坏MVVM模式,如果是这样,为什么以及为什么会这么糟糕呢?
WPF:
<Button Click="Button_Click" />
代码背后:
private void Button_Click(object sender, RoutedEventArgs e)
{
ViewModel.CallMethod();
}
查看型号:
public void CallMethod()
{
// Some code
}
恕我直言,它使代码背后的代码非常简单,视图模型仍然对视图和代码不可知,对视图的更改不会影响业务逻辑。
在我看来,比Commands
或CallMethodAction
更简单明了。
我不想要那种答案&#34;它不应该如何完成&#34;。我需要一个恰当而合乎逻辑的理由,说明为什么这样做会导致维护或理解问题。
答案 0 :(得分:11)
不,这是完全正常。
View的作业可以处理用户输入并与ViewModel进行交互。按钮单击事件处理程序(在调用中调用ViewModel的方法)完全属于此角色。
您发布的内容清晰,可读,高效,可维护,完全符合MVVM设计模式的精神。
现在,从更一般的意义上讲,您真正想要问的是:&#34;为什么选择ICommands,而不是MVVM的事件处理程序?&#34;好吧,你当然不会be | the | first
答案 1 :(得分:2)
不,它不会打破MVVM,只要你不引入更适合视图模型的逻辑。
它有可能降低IMO的清晰度,因为它打破了紧密耦合的XAML和c#文件的视图,并且您无法在一个地方看到所有内容。我发现隐藏零代码更容易,因为这意味着在处理视图时更少的上下文切换。
在UI设计师不是C#程序员的环境中工作也会更具挑战性,因为两个不同的人正在维护紧密耦合的文件。
这是我的意思的一个例子。这是一个周末项目,我在WPF中实现Minesweeper的乐趣和体验。我最大的WPF挑战之一是鼠标输入。对于之前没有浪费时间的人来说,鼠标左键单击显示一个单元格,鼠标右键单击切换单元格上的标记,鼠标中键将(有条件地)显示相邻单元格。
我首先考虑使用System.Windows.Interactivity EventTrigger
和InvokeCommandAction
将事件映射到命令。这种方法适用于鼠标右键(不是真正的点击事件,而是一个MouseRightButtonUp),但对于没有特定操作的鼠标中键,它根本不起作用,只有普通的MouseDown /的MouseUp。我简单地考虑了棱镜在InvokeCommandAction上的变化,它可以将MouseButtonEventArgs传递给它的处理程序,但这很大程度上打破了MVVM概念,我很快就放弃了它。
我不喜欢直接将事件处理程序放在代码隐藏中的想法,因为它紧密耦合了操作(鼠标单击)和响应(显示单元格等)。它也不是一个非常可重复使用的解决方案 - 每次我想要处理中间点击时,我都会进行复制,粘贴和编辑。
我确定的是:
<i:Interaction.Triggers>
<mu:MouseTrigger MouseButton="Middle" MouseAction="Click">
<i:InvokeCommandAction Command="{Binding Path=RevealAdjacentCells}" />
</mu:MouseTrigger>
</i:Interaction.Triggers>
在这种情况下,后面的代码中没有代码。我将它移动到我创建的MouseTrigger
类中,该类继承自System.Windows.Interactivity.TriggerBase
,它是视图层代码,不是任何特定视图的一部分,而是任何视图都可以使用的类。这个处理程序代码尽可能与它所附加的元素无关 - 从UIElement派生的任何东西都可以工作。
通过利用这种方法,我在代码隐藏的事件处理程序中获得了两个关键的事情:
这里的主要缺点是最初设置的工作量更大。我的MouseTrigger类本身比事件处理程序更复杂(主要是围绕正确处理依赖属性及其变化)。对于看似简单的事情,XAML通常也会相当冗长。