在Code Behind事件中调用View Model方法会破坏MVVM吗?

时间:2016-10-20 17:24:47

标签: c# wpf mvvm

我想知道这是否会破坏MVVM模式,如果是这样,为什么以及为什么会这么糟糕呢?

WPF:

<Button Click="Button_Click" />

代码背后:

private void Button_Click(object sender, RoutedEventArgs e)
{
    ViewModel.CallMethod();
}

查看型号:

public void CallMethod()
{
    // Some code
}
恕我直言,它使代码背后的代码非常简单,视图模型仍然对视图和代码不可知,对视图的更改不会影响业务逻辑。

在我看来,比CommandsCallMethodAction更简单明了。

我不想要那种答案&#34;它不应该如何完成&#34;。我需要一个恰当而合乎逻辑的理由,说明为什么这样做会导致维护或理解问题。

2 个答案:

答案 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 EventTriggerInvokeCommandAction将事件映射到命令。这种方法适用于鼠标右键(不是真正的点击事件,而是一个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派生的任何东西都可以工作。

通过利用这种方法,我在代码隐藏的事件处理程序中获得了两个关键的事情:

  1. 事件与行动之间存在松耦合。如果我在UI上使用UXD,他们可以通过编辑一行XAML来更改命令所关联的鼠标按钮。例如,交换鼠标右键和鼠标中键非常简单,不需要.cs更改。
  2. 它可以在任何UIElement上重复使用,与任何特定的UIElement无关。我可以在以后随时解决这类问题时解决这个问题。
  3. 这里的主要缺点是最初设置的工作量更大。我的MouseTrigger类本身比事件处理程序更复杂(主要是围绕正确处理依赖属性及其变化)。对于看似简单的事情,XAML通常也会相当冗长。