The best thing I learned this week was a good way to use MVVM in connection with modal dialogs.I spent a good deal of time scouring the internet for a good answer to this problem. Most of the answers I found involved a lot of code to get up. The issue I have with those kinds of solutions is that if I integrate them into a production project, I’m responsible for supporting them whether I understand all of the code involved or not. I’m sure that over time I’ll acquire the mastery of WPF to be able to create those kinds of solutions, but I don’t have that level of mastery of WPF right now.
The aha moment came with I read this thread: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/0befde65-27e0-43ab-bd9f-6b1df38b7ab3 If you scroll down to the Sergey Pikhulya post (October 8, 2009, 6:42 PM) you’ll find the post I mean. Sergey suggested creating an Interface for IModalViewService, and injecting the an implementation that relies specifically on WPF Windows at run time. In this manner, you can create dummy implementations of IModalViewService for unit-testing your ViewModel.
Honestly, I felt kind of stupid for not thinking of this before. My application already supports injection of configured data services at run time. This is really exactly the same problem with the same solution—just on the presentation/UI layer instead of the data layer.
I thought of a few other solutions to the problem as well.
- Use events. Create events for each time a visual request needs to be made to the user.
- Pros: Easy.
- Cons: you have to create an event for each kind of prompt (message, OK/Cancel, Input).
- Doesn’t easily support specialized data templates for specialized dialogs.
- Leads to an explosion of code as you add new kinds of EventArgs sub-classes.
- You have to write a lot of glue code to make the interaction between MVVM and Xaml happen.
- Create command properties on the ViewModel and assign them in the Xaml.
- Pros: Easy
- You gain good separation because the VM doesn’t need to know how to execute the command, and the use of the dialog is encapsulated in the right layer.
- Cons: You still have a testability problem. If the command logic is complex, you are putting a lot of untestable code in the UI layer.
- Pros: Easy