【问题标题】:MvvM Model Launching DialogsMvvM 模型启动对话框
【发布时间】:2012-06-08 00:03:31
【问题描述】:

我知道有很多关于 ViewModel 应该如何打开对话框、Model 如何启动对话框的问题?

模型是否应该调用一个对话服务,它调用视图模型的对话服务,一直到视图?模型是否应该引用 mvvm-light 工具包?

特别针对我的情况 - 当我的模型被传递一些数据以恢复/解释和构建模型对象时(我认为这应该是模型的工作) - 有可能引发错误。


更新#1:我已经接受了下面的答案,基于来自 fmunkert 的 cmets。我意识到我问错了问题,根本问题是为模型设计一个范式来发出错误信号。

【问题讨论】:

    标签: c# wpf mvvm dialog


    【解决方案1】:

    由于 MVVM 不是标准,并且由于没有明确的权威来决定 MVVM 中什么是正确的,什么是错误的,所以您可以以您认为合适的任何方式实现对话框,只要您不调用任何 WPF 对话框直接来自 ViewModel 或模型。

    在我最近编写的应用程序中,我使用了以下两种方法(使用我自己的 MVVM 框架库):

    • 通过“服务”从 ViewModel 调用模态对话框。 IE。 ViewModel 可以通过ShowModalDialog() 方法获得IFrontend 指针。 IFrontend 有两种通用实现:一种用于 WPF(打开对话框),另一种用于单元测试环境(仅模拟对话框)。

    • 有时可以在 ViewModel 不知道的情况下打开非模态对话框。例如。如果您有一个 ViewModel 用于需要能够打开字体选择对话框的表单,那么这是一个用户界面详细信息,并且 ViewModel 确实需要了解该详细信息。 ViewModel 不关心字体是使用对话框还是使用下拉列表选择的。

    如果您使用 MVVM Light 或 Prism 等第三方库,您可能应该遵循库文档中的建议。

    【讨论】:

    • 感谢您的回复,但您建议如何从模型中打开对话框?在模型中添加 IViewModel 服务似乎不合适。
    • 这取决于您的模型如何发出错误信号。例如,如果模型在错误时抛出异常,请在 ViewModel 中使用 try-catch 处理程序并从 catch 子句打开对话框。
    • 我将此标记为答案,来自您上面的评论。你让我意识到我在尝试做错事。我不应该试图弄清楚如何从模型中打开对话框,我需要弄清楚的是如何从模型中发出错误信号。谢谢!
    【解决方案2】:

    我不确定您是否还在寻求任何帮助,但我在对话框方面采用的方法是让视图模型引发视图可以处理的事件。视图现在可以做任何它想要将数据获取到视图模型的操作,因此您可以毫无问题地在视图中显示对话框。您将对话框中的响应传递给事件的 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 方法所需的数据。我希望这会有所帮助:)

    【讨论】:

      猜你喜欢
      • 2021-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-22
      • 2020-07-27
      • 2011-09-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多