我知道有很多关于 ViewModel 应该如何打开对话框、Model 如何启动对话框的问题?
模型是否应该调用一个对话服务,它调用视图模型的对话服务,一直到视图?模型是否应该引用 mvvm-light 工具包?
特别是针对我的情况 - 当我的模型被传递一些数据以恢复/解释和构建模型对象时(我认为这应该是模型的工作) - 有可能引发错误。
更新 #1:根据 fmunkert 的评论,我接受了以下答案。我意识到我问错了问题,根本问题是为模型设计一个范式来发出错误信号。
由于 MVVM 不是标准,并且由于没有明确的权威来决定 MVVM 中什么是正确的,什么是错误的,所以您可以以您认为合适的任何方式实现对话框,只要您不直接从ViewModel 或模型。
在我最近编写的应用程序中,我使用了以下两种方法(使用我自己的 MVVM 框架库):
模态对话框通过“服务”从 ViewModel 调用。即 ViewModel 有一种方法可以通过方法获取IFrontend
指针ShowModalDialog()
。有两种通用实现IFrontend
:一种用于 WPF(打开对话框),另一种用于单元测试环境(仅模拟对话框)。
有时可以在 ViewModel 不知道的情况下打开非模态对话框。例如,如果您有一个 ViewModel 用于需要能够打开字体选择对话框的表单,那么这是一个用户界面细节,而 ViewModel 确实需要了解该细节。ViewModel 不关心字体是使用对话框还是使用下拉列表选择的。
如果您使用的是 MVVM Light 或 Prism 等第三方库,您可能应该遵循库文档中的建议。
我不确定您是否仍在寻求任何帮助,但我在对话框方面采取的方法是让视图模型引发视图可以处理的事件。视图现在可以做任何它想要将数据获取到视图模型的操作,因此您可以毫无问题地在视图中显示对话框。您将对话框中的响应传递给事件的 EventArgs,以便视图模型拥有它正在寻找的数据以便继续。
例如:
Public Class View
Private WithEvents _VM AS new ViewModel()
Private Sub _VM_AddingItem(Sender AS Object, E AS ViewModel.ItemEventArgs)
Dim Dialog As new SomeDialog()
If Dialog.ShowDialog then
E.Item = Dialog.Item
Else
E.Cancel = True
End If
End Sub
End Class
Public Class ViewModel
Public Sub AddItem(Item AS Object)
Do Some Work here
End Sub
Private Sub _AddItem()
Dim Args AS New ItemEventArgs()
OnAddingItem(Args)
If not Args.Cancel Then AddItem(Args.Item)
End Sub
Protected Sub OnAddingItem()
RaiseEvent AddingItem(me, ItemEventArgs)
End Sub
Public Event AddingItem(Sender AS Object, E As ItemEventArgs)
Public Class ItemEventArgs
Public Property Item AS Object
Public Property Cancel AS Boolean = false
End Class
End Class
然后只需将您的命令连接到_AddItem
仅引发事件以收集该方法所需数据的私有AddItem
方法。我希望这有帮助 :)