Requires reference to System.Windows in my ViewModel?

Jun 28, 2010 at 6:11 PM
My goal was to enable the ViewModel to tell the View to present a MessageBox and ask the user a question. I didn't want the ViewModel to have any reference to Windows-specific code. I take the time to download and install MVVM Light Toolkit. Now I find that even with the toolkit, it is necessary for my ViewModel to reference System.Windows, in order to resolve things like MessageBoxButton and MessageBoxResult. Why go through all this extra work, when you just wind up with a ViewModel that has a reference to System.Windows? I might as well call MessageBox.Show() straight from the ViewModel. Nothing has been saved by using the MVVM toolkit, so I just don't understand why I would use this. Can someone please explain to me, why go through this effort, if I still have to reference System.Windows in my ViewModel? Thanks, Hugh
Coordinator
Jun 28, 2010 at 7:02 PM

Hi,

The reference to System.Windows is needed for the views anyway, which is where the viewmodel belongs. Having a reference to System.Windows does not add any bulk to your DLLs or XAP files if that is what concerns you.

That said, I agree that this is not super clean, and this code will be removed in a future version. In the mean time, you can get the code from here, remove the class named DialogMessage (which you probably do not need anyway) and this removes the need to System.Windows.

Let me know if that helps,

Cheers,

Laurent

Jun 28, 2010 at 7:40 PM
Thanks for replying Laurent, Please forgive me if I'm wrong. I understand MVVM to be useful to separate the design of the View and the code of the ViewModel. You could have a set of Views for WPF and a separate set of Views for Web. The 2 different views could be tied to the same ViewModel in different apps. In this scenario, each of the 2 views would be in separate assemblies (WPF, Web) and the ViewModels would be in their own separate assembly (ViewModel). A web app would reference the Web assembly for its views and the ViewModel assembly for the backing for the Web views. Similarly, in a WPF app, it would reference the WPF views and use the same ViewModel assembly for the code backing. I have never understood any example on the net which shows the Views and the ViewModels in the same assembly, and your comment ("System.Windows is needed for the views anyway, which is where the viewmodel belongs") reinforces that confusion. To me, that seems to defeat the purpose. Why not just use the code-behind feature, if you want your views and viewmodels in the same assembly and there is a 1-to-1 correspondence between Views and Viewmodels? We are just kidding ourselves, that this is a valid architecture. It is just a code-behind and we've made our own life more difficult needlessly. After all, .XAML is separate from .CS so you already have separation of GUI and code built-in, if you're going to put it all in one assembly, what's the point? If anything, MVP architecture makes more sense, because you can at least define an Interface by which the Presenter can talk back out to the View. I do want DialogMessage, my whole point for using MVVM Light was to enable the ViewModel to ask the View to throw up a MessageBox. Kind Regards, Hugh
Coordinator
Jun 28, 2010 at 7:53 PM

Hi,

Yes I understand what you mean. Many consider MVVM to be rather specific to WPF and Silverlight, which is why historically people didn't really place the ViewModels in a separate assembly, except in cases where the number of classes was just too big and having separate assemblies was a better way to keep the overview.

Multiple thoughts here:

  • Using MVVM in ASP.NET will be quite complex due to the lack of databinding infrastructure. This will force you to listen to every PropertyChanged event explicitly. In my opinion MVVM is not the best pattern for frameworks that do not have built-in databinding infrastructure. 
  • ViewModels have multiple advantages within Silverlight/WPF:
    • They facilitate the work with graphic designers by delimiting precisely the responsibility of each person in the project.
    • They make the work in Blend much easier (for technical reasons that I don't want to go too deep into here)
    • They make the code more testable. While possible, it is much more difficult to test code behind/event handlers than viewmodels/commands
    • They make it easier to refactor the code
    • They allow the view to be much thinner, so that replacing it by something else (such as in Windows Phone 7 projects) is trivial, and reusing the same VM code.

These are the main advantages of MVVM and why people are using it mostly. That would answer the question of knowing why one would use MVVM instead of just the code behind.

Regarding sharing code between WPF and Silverlight (and windows phone 7), the sharing is often done at code level (linked code files) instead of assembly level. Sharing at assembly level used to be impossible between WPF and SL because of binary incompatiblity. It is a little better now, but still a problem sometimes (and still a problem between SL and WP7). So instead we rather use a different assembly but link the code files to share (most of) the code.

Regarding your need to display a MessageBox from the ViewModel (a common need), you don't actually need DialogMessage to do this. Instead a common pattern to do that is to use an IDialogService interface that a class from the View implements (for small project I let the MainPage implement IDialogService). Then, this instance needs to be passed to the ViewModel (for example after the view is initialized). The interface has a set of methods such as void ShowMessage(string), bool AskUser(string), Stream OpenFile(string path), etc... All these methods use various dialogs, but the point is that there is no view related classes or enums there, so the separation is better.

Does that make sense?

Cheers,

Laurent

Jun 28, 2010 at 10:50 PM
Thanks Laurent, your insight is very valuable. I like the idea of passing an Interface to the ViewModel which allows it to call functions out on the View. Reminds me of MVP ;) Have a nice evening. Kind Regards, Hugh