One of the great things that MVVM has achieved is removing the dependency on the View in the ViewModel (Presenter). Occasionally, however, I run into situations where I really need to know what View the ViewModel is associated with.
I need to create a dialog; which window is the owner? Or which control is the owner for pop-ups?
I want to change the Visual State with a call-back ; Which control do I pass to the VisualStateManager?
Having rejoiced that I no longer have a dependency on the View from my ViewModel, how do I get a reference to a ViewModel’s View?
The best solution I have seen thus far is the concept of a ViewRegistry. The ViewRegistry is dictionary of Views keyed by the View’s ViewModel. A View that knows it uses Dialogs or the VisualStateManager, for instance, registers itself with the ViewRegistry via an attached property. The ViewRegistry adds the View using it’s DataContext (the ViewModel) as the key. The View Registry handles the removal of unloaded views to ensure memory leaks don’t occur.
<UserControl pc:ViewRegistry.Register="true" ... >
It’s also good to note that a “View” can also be any control inside an actual view, this can be useful with things like the PopUp Dialog where you want the dialog to control a portion of a view.
<Grid pc:ViewRegistry.Register="true" ... >
I shy away from ever injecting the ViewRegistry into a ViewModel, as this starts to bring back the coupling MVVM fought so hard to remove. Rather being viewy the ViewRegistry is used in more viewy services like the Dialog Service or Visual State Manager Service.
A View can be retrieved like this:
UIElement view = viewRegistry.FindViewFor(viewModel);