3

I'm trying to learn how to use WPF commands, and how they fit into the MVVM pattern. I understand that some controls, like a button or menu, have a Command property which when set to an instance of an ICommand class connects the button to that command. Once this is set the button will then disable and enable with the CanExecuteChanged event of the command, and clicking the control will call the Execute method of the command.

However, where should the instance of each ICommand live? I've seen various different options in tutorials and I'm not sure which is correct. In some examples a static "ApplicationCommands" class is created and an instance of each command is assigned to a static property of that class. In other examples I've seen commands set as properties of the ViewModel, and in others of the View/Window itself. What's the preferred place for the command instances to live?

Also, how does a command relate back to the View, View Model, or Model? Which of these components should the command be aware of and or manipulate? What should happen when a command is executed? Should it call some method of the Model which then communicates changes back to the View Model/View? Or should a command communicate to the model through a method of the View Model?

4

2 回答 2

1

在某些示例中,创建了一个静态“ApplicationCommands”类,并将每个命令的实例分配给该类的静态属性

您对希望能够从任何地方访问的命令执行此操作。例如,如果您想要一个F1始终显示帮助屏幕的键绑定,那么您将在一个全局可访问的位置实现此命令,然后从各个屏幕绑定到它。

see 命令设置为 ViewModel 的属性,以及 View/Window 本身的其他属性。

如果命令正在处理数据,那么 ViewModel 是它的好地方。如果命令不需要对数据做任何事情,则将其放在 View 后面的代码中(因为它与 ViewModel 无关,您不需要用它污染 ViewModel)。一个有趣的情况是,当您正在执行诸如弹出对话框以响应击键之类的操作时,您需要将当前选定的网格项传递给对话框 - 命令应该放在哪里?在这种情况下,我会将它放在视图后面的代码中,因为没有令人信服的理由将它放在 ViewModel 中 - 如有必要,视图可以从 ViewModel 中检索所选项目。

很多时候,我看到不必要地将命令放入 ViewModel 只是因为人们认为这是唯一的方法。我使用的经验法则是:如果它正在做与 UI 相关的工作,那么它属于视图背后的代码。如果它正在做与数据相关的工作,那么它可以进入 ViewModel。如果它正在混合使用,请考虑在 View 和 ViewModel 之间分解功能。

命令应该注意和/或操纵这些组件中的哪些?

只有它需要知道的那些。从 ViewModel 访问像模型这样的组件应该通过正确定义的属性或返回接口的函数来完成,这是为了避免紧密耦合。

它是否应该调用模型的某些方法,然后将更改传回给视图模型/视图?

从 ViewModel 访问模型的命令没有问题。该命令可以更新 ViewModel 或 Model 上的属性,并且通过数据绑定和属性通知的魔力,这些更新可以反映在 UI 中。

于 2012-03-01T00:20:56.367 回答
1

使用静态命令的方法通常采用与RoutedCommands任何特定对象的状态无关的具有广泛应用的命令。如果您使用在构造函数中将其方法传递给它们的动态实现,ICommand它们通常是ViewModel与该命令相关的实例。

这些命令可以作用于 ViewModel 和 Model,如何操作取决于您,我通常只是从命令中调用 VM 上的相应方法,Execute以保持命令初始化代码简洁。

我真的不能告诉你最好的方法是什么,也许其他人对什么时候什么时候什么效果最好以及为什么效果有更深入的了解。

于 2012-03-01T00:10:38.717 回答