Reputation: 32463
How to call MessageBox.Show()
based on the result of ViewModel
method?
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
View
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 have a button which Click event bounded to the Command property
I understand MVVM as simple separating of concerns.
View (In Winforms this is Form) have only own logic. Doesn't matter designer code or codebehind.
ViewModel
know about Model but didn't know about View.
Now I am little bid stack about how MessageBox
can be called based on the result of Save
Command/Method while keeping View
and ViewModel
separeted?
Because MessageBox.Show is obviously a part of the View
At this moment i use workaround which on my opinion breaking MVVM
pattern.
MessageBox.Show
executed from ViewModel inside SaveModel()
method if _Model.Save
returns false
I have checked answer WPF MessageBox with MVVM pattern?, but at this moment wasn't influenced by using some intermediate types. I trying to keep Views and ViewModels in the different project, and Views haven't any references to other application libraries excepts resources
@HighCore, I know difference between Winforms
and WPF
:)
Upvotes: 0
Views: 945
Reputation: 17848
As a visual element, any message box is in fact, part of a View. Thus, if you show your message box directly from a ViewModel
(define a command that calls the MessageBox.Show()
method), this simple code will break the main MVVM concept - ViewModels must not refer to Views - and make it impossible to write unit-tests for your ViewModel. To get around this difficulty, the you can use services concepts. A service is a kind of IOC concept that removes any references between a ViewModel and View layers. In code, a service is an interface used within the ViewModel code without any assumption of "when" and "how" this interface is implemented:
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
You can provide you View Model with IMessageBoxService
implementation using DI/IoC.
P.S. If you're using DevExpress WinForms controls you can extend your MVVM app with cool things like POCO-ViewModels, bindings&commanding, services, messenger and etc. - all the fully adapted for WinForms environment.
Upvotes: 3