Anybody come across a clever way of closing a view in a viewmodel using MVVM?
Maybe there is a way of using binding to signal the view (window) to close?
I would really appreciate any input anyone has.
Basically i have a loginView that is bound to a loginViewModel, in the viewmodel (using binding on a command) i test to see if the login is successful and if it is i basically load up a new View (mainview) and attach its datacontext...
but i still have the loginView shown - so i need to signal it to unload..
I was also hoping for a generic solution because i am sure that i am going to need to do this sort of thing in other situations
Any ideas?
Not sure what MVVM framework you are using, but most contain some sort of messaging / notification solution that is easy have things register for messages which are sent. There is no reason that I can imagine that your view could not register for a message such as "CloseWindowsBoundTo" and the viewModel as the sender. Then in your view, you can just register for that message, and compare your current datacontext to the sender. If they match, close the window.
Simple, and keeps your view abstracted from your viewmodel.
Here would be my approach using MVVM-light toolkit:
In the ViewModel:
And in the View:
To close the view from viewmodel i used the Galasoft MVVM Light Toolkit which you can download here: http://www.mvvmlight.net/
create a class like this: public class ClosingRequested : MessageBase { }
add this to your view constructor: Messenger.Default.Register(this, vm, msg=> Close());
call this to close your window: Messenger.Default.Send(new ClosingRequested(), this);
I would use an ApplicationController which instantiates the LoginViewModel and shows the LoginView. When the user proceeds with the login screen the ApplicationController closes the LoginView and shows the MainView with its MainViewModel.
How this can be done is shown in the sample applications of the WPF Application Framework (WAF) project.
Generally you would use some kind of controller/presenter/service to drive the screen activation/deactivation. MVVM is not meant to be the One Pattern to Rule Them All. You will need to combine it with other patterns in any non-trivial application.
That said, in some situations in makes sense to have a view model that manages the life cycle of child view models. For example, you might have an
EditorViewModel
that manages a collection of child view models - one for each document being edited. In that case, simply adding/removing to/from this collection can result in the view activating/deactivating. But this does not sound like it fits your use case.Just close in an EventHandler in code behind and handle everything else in the view model where you can use a command binding.
You can also do this using event. Though you need like 3 lines of codes in your view code behind (some MVVM purist don't like this);
In your viewmodel, you create an event that the view can subscribe to:
In your, view you subscribe to the event after your initializecomponent method as below:
You just simply call RaiseClose() when you are ready to close the View from the ViewModel.
You can even use this method to send message to the view from the viewmodel.
The event can be put in an interface to avoid direct dependence of the view on the viewmodel.