【问题标题】:Can a ViewModel talk to View in MVVM pattern?ViewModel 可以与 MVVM 模式中的 View 对话吗?
【发布时间】:2011-01-17 18:39:02
【问题描述】:

在 MVP 模式中,Presenter 具有 View 接口,因此 Presenter 可以调用 iview.DoSomething().. 在 MVVM 模式中呢?

根据John Gossman 的UML 图http://blogs.msdn.com/johngossman/archive/2006/04/13/576163.aspx,ViewModel 没有View 的接口。因此,似乎 ViewModel 和 View 应该仅通过 Binding 进行通信。 (或使用附加属性或混合行为等)。

你们怎么看?

【问题讨论】:

  • 嗨 Skaffman,谢谢.. 你编辑了什么? :)
  • 他添加了设计模式标签。通过单击“已编辑”文本检查编辑历史记录。
  • 谢谢...太好了...我没有看到“已编辑”文本。我只看到“edit|rollback|delete|flag”。无论如何,感谢您为我的帖子添加了一个标签...

标签: wpf silverlight design-patterns mvvm


【解决方案1】:

ViewModel 可以与 MVVM 模式中的 View 对话吗?

是的,但是以一种解耦的方式。允许引入接口IView进行通信。

MVVM 模式即将将逻辑从 View 移动到 ViewModel。这样我们就可以对这个逻辑进行单元测试。

【讨论】:

  • 很久以前看过WAF。我看到WAF的创建者在Demo后面的代码中设置了密码。不知道他为什么这样做。 >>是的,但是以一种解耦的方式。那么,MVP 和 MVVM 模式之间有什么区别呢?我们也可以将逻辑移至 MVP 中的 Presenter。你认为从 ViewModel 中设置 iview.DoSomething 可以吗?
  • 从解耦和可测试性的角度来看,绝对允许从 ViewModel 调用 IView.DoSomething。如果您改用 Binding,则定义 ViewModel 的属性。所以 View 知道 ViewModel 的属性。只是Binding使用了Reflection(不是类型安全的)但是耦合是一样的。
  • 为了解耦和可测试性,我们甚至不需要使用 MVVM 模式。 MVC 或 MVP 等也是可测试的。我还有两个问题。 1)如果你说ViewModel里面有View的界面就可以了。你能告诉我MVP或MVVM之间的区别吗?您也可以在此链接groups.google.com/group/wpf-disciples/browse_thread/thread/… 中阅读我与 Glenn 的讨论。 2) 你认为在 View 中也可以做 ((ViewModel)this.DataContext).DoThat() 吗?
  • 1) 对我来说,MVVM 与 PresentationModel 模式 (martinfowler.com/eaaDev/PresentationModel.html) 相同,这也是 Microsoft p&p 团队 (msdn.microsoft.com/en-us/library/cc707885.aspx) 的意见。 2) 是的,我相信这样做是可以的:((ViewModel)this.DataContext).DoThat()。允许 View 知道其关联的 ViewModel。
  • MVVM = PresentationModel。但是如果可以做到 ((ViewModel)this.DataContext).DoThat() 那么为什么人们要创建附加属性或混合行为.. 如果您查看其他人的回复,那么大多数人认为 View 和 VM 之间的通信是仅绑定..
【解决方案2】:

它通常会发生 - 通过 INotifyProperty 上的事件发生变化,如果没有别的。

【讨论】:

  • 对不起。我没听懂。。你是说在 VM 中有一个 View 界面吗?
  • 假设您使用的是 C#,在 INotifyPropertyChanged 接口上公开的事件通常由 View 侦听(通过数据绑定)。数据绑定并不是真正的魔法——它只是将处理程序连接到 INotifyPropertyChanged 和 INotifyCollectionChanged 上的事件。但是,是的,我会说通常虚拟机确实会与视图对话,以通知它数据更改。不过,它有一个抽象视图的想法,而不是一个特定的实现——它的通信应该限制在“this changed”而不是“so change this control”
  • 是的。所以,“这改变了”限制 = 数据绑定,对吗? :)
  • 是的 :) 但我实际上并没有看到其他类型的通信有问题,只要它基本上是正在发送的数据,并且不知道视图泄漏。其他人可能比我更纯粹:)
【解决方案3】:

我同意约翰·戈斯曼的观点。 ViewModel 与 View “对话”的方式仅通过 Bindings。事实上 - ViewModel 根本不应该关心 View。它应该通过属性简单地使数据可用,并且由 View 决定它将在 ViewModel 中动态绑定到什么。如果 ViewModel 想要告诉 View 一些事情,这应该通过 Bindings 隐式发生。

一个小时前有人问了一个类似的问题 - here

【讨论】:

  • 非常感谢。我也同意这一点。我在写michaelsync.net/2010/02/03/rules-of-mvvm这个帖子的时候,有人说ViewModel里有view的界面就可以了。我告诉他们这将是一个 MVP 模式。当然,我们可以混合模式,但我认为在 VM 中使用 View 的界面违反了 MVVM 模式。谢谢你的回答。我真的很感激。
  • 听起来你在正确的轨道上。很高兴有帮助。将查看您的博客文章! :-)
  • 谢谢。如果您对该帖子有任何意见或建议,请告诉我.. :)
  • 不错的帖子 :-) 我喜欢的一件事是我可以让模型类全部干净——不要仅仅因为视图需要它而在那里添加东西。例如。我不必仅仅因为 View 想要对其进行排序而对某些列表进行排序 - 这就是 ViewModel 来处理的问题。但是您已经通过说模型可以是普通的 DTO 来涵盖这一点。
  • 谢谢,Stain.. 大多数人都同意我在那篇文章中提到的关于 MVVM 的所有事实(除了一个).. 人们不同意的唯一一件事是有些人认为他们可以在 ViewModel 中有一个视图界面。
【解决方案4】:

MVVM 的全部目的是大大减少 WPF 表单或用户控件的代码隐藏类中的代码量。这个想法是,任何将由经典 MVC/MVP 中的视图处理的东西都可以通过使用数据绑定和/或命令的组合转换到 VM。在我对 MVVM 的一般使用中,我设法完全删除了我的表单/用户控件中的所有代码隐藏,并且 VM 不直接了解它所控制的视图。如果您遇到的情况确实无法通过数据绑定或命令处理,那么请详细说明您最初的问题,我(或此处众多、更有才华的 MVVM 人员之一)将尝试为您指明正确的方向.

【讨论】:

  • 谢谢。问题来了~你觉得ViewModel中有View的接口违反了MVVM模式吗?示例:IPersonView、PersonView 和 PersonViewModel.. 和 PersonViewModel 有 IPersonView...
  • 您好,很抱歉错过了评论,看到您接受了 Stians 的回答,但为了完整起见,这是我的回复。我确实认为它违反了 MVVM 模式(在我的理解中),并且正如现在提到的那样,通过暴露的属性使用数据绑定是更新视图的方法。很高兴你得到了答案:)
  • 谢谢,伙计...实际上,您的帖子也回答了我,但这里的问题是我不能将多个帖子标记为已回答。由于 MVVM 模式没有标准规则,也没有所有者/创建者,我们需要询问大家是否都同意这一点.. :) 这就是为什么我在不同社区询问有关 MVVM 的问题并写下总结信息在我的一篇文章中..
猜你喜欢
  • 1970-01-01
  • 2014-01-14
  • 1970-01-01
  • 2011-08-03
  • 1970-01-01
  • 2011-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多