So my first attempt did everything out of the code behind, and now I'm trying to refactor my code to use the MVVM pattern, following the guidance of the MVVM in the box information.
I've created a viewmodel class to match my view class, and I'm moving the code out of the code behind into the viewmodel starting with the commands.
My first snag is trying to implement a 'Close' button that closes the window if the data has not been modified. I've rigged up a CloseCommand to replace the 'onClick' method and all is good except for where the code tries to run this.Close()
. Obviously, since the code has been moved from a window to a normal class, 'this' isn't a window and therefore isn't closeable. However, according to MVVM, the viewmodel doesn't know about the view, so i can't call view.Close()
.
Can someone suggest how I can close the window from the viewmodel command?
You don't need to pass the View instance to your ViewModel layer. You can access the main window like this -
I see no issue in accessing your main window in ViewModel class as stated above. As per MVVM principle there should not be tight coupling between your View and ViewModel i.e. they should work be oblivious of others operation. Here, we are not passing anything to ViewModel from View. If you want to look for other options this might help you - Close window using MVVM
MVVM-light with a custom message notification to avoid the window to process every notificationmessage
In the viewmodel:
Register the message in the window constructor:
This is taken from ken2k answer (thanks!), just adding the
CloseCommand
also to the baseCloseableViewModel
.Your view model, inherits it
Then on you view
My solution to close a window from view model while clicking a button is as follows:
In view model
In View, set as follows
I do it by creating a attached property called DialogResult:
then write this to you XAML, in the window tag
finally in the ViewModel
if you change the Close to true, the window will be closed
This is very similar to eoldre's answer. It's functionally the same in that it looks through the same Windows collection for a window that has the view model as its datacontext; but I've used a RelayCommand and some LINQ to achieve the same result.