The application I’m currently writing is using MVVM with the ViewModel-first pattern. I have XAML similar to the following:
<ContentControl Content="{Binding FooViewModel.BarViewModel.View, Mode=OneWay}"/>
Every VM is a DependencyObject. Every property is a DependencyProperty. Depending upon the state of the application, the value of the BarViewModel property of the FooViewModel can change, thus changing the value of the View property. Unfortunately when this happens, the new view is not displayed, and the old one remains.
This is extremely frustrating. I thought that if any part of a path expression changed, the binding would update, but that doesn’t appear to be the case. When I’ve used shallower path expressions, such as FooViewModel.View and I’ve changed the value of the FooViewModel property, that has updated the ContentControl to which it’s bound, but not in this case.
If your solution is that I abandon ViewModel-first, that is not an option, though I appreciate your advice. I must get this working as is.
CLARIFICATION
This is a question about data binding, and not about MVVM or how to implement it. You can safely ignore the MVVM aspects of this if it helps you to think about the problem, or if you have a different idea about how MVVM should be implemented. This is a large, existing project in which the MVVM design pattern cannot be changed. (It is far too late for that.)
So, with that said, the correct question to be answering is the following:
Given a binding path expression in which every element is a DependencyProperty and the final property is a view bound to a ContentControl, why does a change in a property in the middle of the path not cause the binding to update?
Although I would expect this to work, there are several problems with your approach.
Firstly, your view models should not use
DependencyObjectorDependencyProperty, this ties them in to WPF. They should instead implementINotifyPropertyChanged. This makes your view models reusable in other presentation technologies such as Silverlight.Secondly, your view models shouldn’t have references to your views, so you shouldn’t require a
Viewproperty on your view models.I would seriously consider using an MVVM framework for view composition – Caliburn.Micro, for example, makes view model first development extremely straightforward, and already provides a view model base class which implements
INotifyPropertyChanged, and a mechanism for building view compositions with conventions.I.e. you can have a conductor view model which has an
ActiveItemproperty, and you simply place aContentControlon your view with the same name as the property:You can use the
ActivateItem()method to change the current active item.Caliburn.Micro also has a host of other features, such as being able to place a
Buttoncontrol withx:Name="Save"on your view, and yourSavemethod on your view model will automatically be invoked when the button is clicked.