如何根据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
命令/方法的结果,在保持Save
和View
分开的情况下如何调用ViewModel
,我是一个很小的投标堆栈?
因为MessageBox.Show显然是View的一部分
此时我使用的解决方法在我看来打破了MVVM
模式
如果MessageBox.Show
返回false,则在SaveModel()
方法内从ViewModel执行_Model.Save
我已经检查了答案WPF MessageBox with MVVM pattern?,但此时并未受到使用某些中间类型的影响。我试图将Views和ViewModels保留在不同的项目中,而Views除了资源外没有对其他应用程序库的任何引用
@HighCore,我知道Winforms
和WPF
之间的差异:)
答案 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环境。