MVVM中的VM角色 - 它应该处理所有事情吗?为什么?

时间:2012-03-10 23:48:52

标签: mvvm

采用VM的限制究竟在哪里,以便能够更好地适应特定的视图?例如:

在UI(ex按钮)中应该有一个允许添加新项目的命令。附加要求可以是应该选择新项目,确保其在控件上可见(让我们说TreeView控件),并开始编辑新添加的项目(以便更改在VM中设置的预定义值)。让我们假设控件没有自动机制来实现这一点,所以我们需要手动完成。所以执行流程如下所示:

  1. 在VM上调用add命令 - 完成了View的xaml。
  2. 将SelectedItem设置为新项目(通常我们将控件的SelectedItem属性绑定到VM的CurrentItem属性,然后将新项目分配给CurrentItem。
  3. 确保新项目在控件上可见 - 这必须在后面的View代码中完成。
  4. 开始编辑 - 必须在后面的View代码中完成。
  5. 现在,因为网上到处都有关于几乎所有内容使用消息的文章,这个问题是:

    如果我以简单的旧方式做什么,我该怎么办?我在添加新项目时使用Click事件而不是Command绑定,在方法中我这样做:

    // in View's Click event handler
    ViewModel.AddCommand.Execute(null);
    EnsureVisibleSelectedItem();
    BeginEdit();
    

    ..干净清晰!如果我使用消息做什么,我会得到什么:

    // in ViewModel's AddCommand
    AddNewItem();
    SetCurrentItem();
    SendMessageToEnsureVisibleSelectedItem();
    SendMessageToBeginEditSelectedItem();
    

    ... View已注册接收这两条消息。

    对此非常感谢。在我看来,UI可以改变,VM应该能够采用新的UI而不需要对其自身进行更改,所以我不太了解在互联网上传播的当前MVVM策略。

1 个答案:

答案 0 :(得分:3)

我会说“让它变得简单”。

MVVM中非常重要是:

  • 不依赖于视图的内容应该放在ViewModel 中(您的ViewModel不得以任何方式了解视图 - 不仅仅是通过对象引用)
  • 视图中的所有其他内容及其代码隐藏

是的,在其代码隐藏中。如果代码与视图相关而不是逻辑,那么编写代码隐藏没有任何问题。例如,拖拽和drop管理应该写在代码隐藏中。

要回答你的问题,你不要以书面形式破坏任何内容:

// in View's Click event handler
ViewModel.AddCommand.Execute(null);
EnsureVisibleSelectedItem();
BeginEdit();

与视图无关的所有内容都在ViewModel中,View / code-behind中的其他所有内容。那没关系。

不,如果我看你的第二个例子:

// in ViewModel's AddCommand
AddNewItem();
SetCurrentItem();
SendMessageToEnsureVisibleSelectedItem();
SendMessageToBeginEditSelectedItem();

AddNewItem没问题(与视图无关),SetCurrentItem没问题(与视图无关),但SendMessageToEnsureVisibleSelectedItemSendMessageToBeginEditSelectedItem呢? EnsureVisible通常对树视图很有用,但如果您的视图不是使用树视图构建的,该怎么办?如果控件会自动显示新选中的项目怎么办?当然你可以忽略这条消息,但是你会在ViewModel中编写一些无用的代码,因为你认为你的视图需要用于UI显示。

您通常会在ViewModel中编写一些代码,知道View应该如何工作。 是的,你减少了代码隐藏中的行数,但你肯定已经打破了模式

您的“旧时尚方式”实际上是满足您需求的好方法。您的ViewModel不知道该视图,这是重要的。