Sunday, April 03, 2011

Open Window, Dialog or Message Box from a ViewModel – part 2

In my previous post I have shown how to open a Window bound to a view-model triggered by the view, using a simple Action. In this post I'll show how to open a Window, triggered by the view-model.
Opening a window directly by the view where the view decides when a Window should be opened, is an incorrect approach since the view shouldn't make that decision. This decision belongs to the Application layer and not the Presentation layer.

What if the view shouldn't be opened because of application state, user permissions or any other application decision?

In that case the view-model should decide and then trigger the Window or View creation.
Revisiting the problem again, we've got a MessageListViewModel, MessageListView for the email messages view and MessageDetailsViewModel, MessageDetailsView for the email details view should be presented inside a MessageDetailsDialog.

Now instead of attaching a simple Action to the view, we should delegate the request to the view-model by saying: "Hey, I'm the view, someone double-clicked an item, FYI!", using the same trigger, but now invoking a command on the view-model, this would be Phase 1. Next the view-model should decide how to continue on by changing a property for example, and this would be Phase 2. Finally an action bound with the view-model decision property will popup the Window, and this would be the final phase. Of course, the view-model should be asked and be notified again whenever the user closes the Window.
For phase 1, I'll use a simple trigger with invoke command action.

For phase 2, I'll have a bool property on the view-model, notifying that a Window should be opened.
For the final phase, I'll have an Action attached with the view which creates the Window on property change.