使用MVVM模式在Winforms中显示MessageBox

时间:2015-10-25 16:31:35

标签: .net winforms mvvm

如何根据MessageBox.Show()方法的结果来调用ViewModel

视图模型

Public Class PersonViewModel
    Inherits ViewModels.ViewModelBase 'basic INotifyPropertyChanged staff

    Private _Model As Person
    Public Property FirstName As String
    Public Property LastName As String

    'BasicSub is class implemented ICommand taking Execute method as parameter
    Public Property SaveCommand As New Commands.BasicSub(AddressOf Me.SaveModel)

    Private Sub SaveModel()
        If _Model.Save() = False Then
            'Here inform View about saving wasn't successful
        End If
    End Sub
End Class

查看

Public Class PersonView 
    Inherits Form

    'I use BindingSource for bindings
    Private BindingSourceViewModel As BindingSource

    Public Sub New(viewmodel As Object)
        Me.InitializeComponents()

        Me.BindingSourceViewModel.DataSource = viewmodel
    End Public

End Class

View有一个按钮,Click事件被绑定到Command属性

我将MVVM理解为简单的关注点分离 视图(在Winforms中这是Form)只有自己的逻辑。与设计师代码或代码隐藏无关 ViewModel了解模型但不了解View。

现在,根据MessageBox命令/方法的结果,在保持SaveView分开的情况下如何调用ViewModel,我是一个很小的投标堆栈?
因为MessageBox.Show显然是View的一部分

此时我使用的解决方法在我看来打破了MVVM模式 如果MessageBox.Show返回false,则在SaveModel()方法内从ViewModel执行_Model.Save

我已经检查了答案WPF MessageBox with MVVM pattern?,但此时并未受到使用某些中间类型的影响。我试图将Views和ViewModels保留在不同的项目中,而Views除了资源外没有对其他应用程序库的任何引用

@HighCore,我知道WinformsWPF之间的差异:)

1 个答案:

答案 0 :(得分:3)

作为视觉元素,任何消息框实际上都是视图的一部分。因此,如果直接从ViewModel显示消息框(定义一个调用MessageBox.Show()方法的命令),这个简单的代码将破坏MVVM的主要概念 - ViewModels不能引用视图 - 并且make无法为ViewModel编写单元测试。要解决这个难题,您可以使用服务概念。服务是一种IOC概念,它删除ViewModel和View层之间的任何引用。在代码中,服务是ViewModel代码中使用的接口,没有任何假设"当"和"如何"这个界面实现了:

Public Class PersonViewModel
    Protected ReadOnly Property MessageBoxService() As IMessageBoxService
        Get 
            Return Me.GetService(Of IMessageBoxService)()
        End Get 
    End Property
    Public Sub Save()
        If Not _Model.Save() Then
            MessageBoxService.Show("Something wrong!")            
        End If
    End Sub 
End Class

您可以使用DI / IoC为您提供IMessageBoxService实施的视图模型。

P.S。如果您正在使用DevExpress WinForms控件,您可以使用POCO-ViewModels, bindings&commanding, services, messenger and etc.等酷炫的东西扩展您的MVVM应用程序 - 所有这些都完全适用于WinForms环境。