Handling dialog windows in WPF using MVVM pattern is not such obvious thing as people may suspect. There are many discussions about it, and people come out with some solutions, that are more or less difficult, but still not perfect. I don’t like any and it made me describe my own.
As I have found, there is a couple of solutions for the problem. The most common ones are:
- DialogService – creating a service used to handle all dialogs/windows in the application. Such a service can be used by any ViewModel. This way the view model knows that some other part of application must be shown/hidden as a dialog window. It’s somehow a design smell (link1, link2, etc.)
- Dialog content injection – declare a markup of the dialog in XAML. Such a markup is then used to generate the new dialog window. Its visibility is controlled by a binding between ViewModel’s “Showing” property and the View. I thinks it’s better than the first one, but there’s too much logic behind the scene (link)
I think both solutions don’t answer my real need. I had a chat with an architect about this and we came to some simple conclusions:
- MVVM is to create a good separation of presentation layer and the rest of the application, mainly by using bindings
- Showing some UI parts as a dialog window or a panel, tab, accordion etc. is a presentation detail. It should be responsibility of the to control such a behaviour.
- View doesn’t need to be stupid. WPF+MVVM developers got used to moving all the view code to bindings, but let’s not overuse it. If something is simpler to be done in code-behind, let it stay there.
In the end, I decided to invoke the famous “ShowDialog” method in the code-behind and pass the context (view model) to the newly created window. In the simplest case the view should not process the DialogResult, because this is the view model’s role. In my case the communication between the view model of the “Main window” and view model of the “dialog window” is based on events. Such a “Save” event exposed by the dialog’s view model can be used by “Main window” view model to add some item to a collection/repository but in the same time it can be used by the view of “dialog window” to close it.
The most beautiful words will never reflect the beauty of a sample, so here it is: Download