views:

848

answers:

2

Currently there are a lot of variations on the MVVM design pattern but as I understand it the view is allowed to have dependencies on the viewmodel. A colleague of mine disagrees but he couldn't provide a satisfactory explanation.

E.g. my views contain a reference to their viewmodel. This is not needed for all views but it helps when communicating certain events to the viewmodel that can't be done with an ICommand.

Is it OK to have this dependency? What are the disadvantages?

+1  A: 

Coupling through databinding alone is really nice, but sometimes the view needs more than commands and properties from the view model. I have a view that needs to respond to events in the view model, and these events can't be routed events. So this view needs a reference to its view model.

I think it is a good idea for the view to attempt to cast its DataContext (usually inside of the DataContextChanged event) to the right interface type. This way, the view can still be initialized through data templates and other XAML. If you force the interface to be passed in the constructor you have to create the view in code.

Josh G
+6  A: 

The primary metric is: can you test it?

The view absolutely needs a reference to the view model. How else would it get the information it needs to display itself? Usually just having the view model in the DataContext of the view is sufficient, but that still constitutes a dependency. Without the VM in the DataContext, the view would be useless.

Sometimes you need the view to call back to the VM. Normally I just do this in my code behind:

public MyViewModel ViewModel
{
    get { return DataContext as MyViewModel; }
}

private void _someEventHandler(object sender, EventArgs )
{
    ViewModel.SomeMethod();
}

Holding a reference to the view from the view model is where you need to be careful. If the VM depends on a particular view implementation, it is tightly coupled to the view and difficult to test as a result.

If the VM needs to interact in some fashion with the view, you can abstract the requirements into an interface and have the view implement that interface. Then, when the view loads, it can provide the VM with a reference to itself with which the VM can interact.

HTH, Kent

Kent Boogaart
And the reason to talk through an interface as Kent suggests is that you can mock this up for tests. You can create a dummy view that implements this interface for the perpose of testing.
Josh G