Using MVVM in WPF, should I launch child windows from View code behind, or ViewModel?
I usually handle this by creating some sort of WindowViewLoaderService. When your program initializes you register your Window's and your ViewModels with code something like this:
WindowViewLoaderService.Register(TypeOf(MainWindowView), TypeOf(MainWindowViewModel));
WindowViewLoaderService.Register(TypeOf(MyWindowView), TypeOf(MyWindowViewModel));
Then when you can for example call into this service from your ViewModel and all you have to reference is your other ViewModel. For example if you are in your MainWindowViewModel you might have code like this:
var myChildWindowVM = new MyWindowViewModel();
WindowViewLoaderService.ShowWindow(myChildWindowVM);
The WindowViewLoaderService would then look up what View is associated with the specified ViewModel you passed it. It will create that View, Set its DataContext to the ViewModel you passed in, and then display the View.
This way your ViewModels never know about any Views.
You can roll your own one of these services pretty easily. All it needs to do is keep a Dictionary with the key being your ViewModelType and the value being your ViewType. The Register method adds to your dictionary and the ShowWindow method looks up the correct view based on the ViewModel passed in, creates the view, sets the DataContext, and then calls Show on it.
Most MVVM Frameworks provide something like this for you out of the box. For example Caliburn has a slick one that just uses naming convention its called ViewLocator in this Framework. Here is a link that summarizes: http://devlicio.us/blogs/rob_eisenberg/archive/2010/07/04/mvvm-study-segue-introducing-caliburn-micro.aspx
Cinch on the other hand calls it a WPFUIVisualizerService which you can see in action here: http://www.codeproject.com/KB/WPF/CinchIII.aspx
These should help get you rolling.
Well, one remark to start with is that, "Having no code AT ALL in the code-behind" is actually a "myth". If you want to be pragmatic, and you see that having some code (as little as possible would be better), will make your life easier and solve your problem, then you should go with that.
However, in this situation, there are actually some loosely coupled ways to do this. You could have a service that does the interaction for you. You initiate the interaction with the user from the ViewModel, the service takes care of that (by showing a ChildWindow for example), and gives you back the user's reponse. That service can be mocked for testing easily. And it can be tested seperately.
That is, if you want to do things yourself. If you want a framework to do the heavy lifting for you, you can check out the InteractionRequest
functionaity offered by Prism. Here's the MSDN article that talks about adanced MVVM scenarios which includes a section on User Interaction Patterns. That's the way I do it, and it's pretty simple, elegant and straightforward.
Hope this helps :)
To take Matt's answer one step further, you can have all your view's be a user control. Then create a ViewContainer, which is a window with your data templates (as you described).
Then you just ship the viewmodel you wish to open over to the window service, which sets the DataContext. The service would then open the window and the contentcontrol will resolve the correct view for the viewmodel.
This means all the registration is done in the XAML and the window service just knows how to do just that...open and close windows.