Working with the MVVM template, I have a couple of classes of presentation models that represent a two-level hierarchy of data, each of which has a corresponding UserControl that represents its presentation. Both classes of the view model implement INotifyPropertyChanged , and the root level view model provides a property that is related to both its own view and the view of the child.
In the root level view, the root level view model is considered as a data context and explicitly assigns the data context to the view it contains. However, it must also bind one of the properties of the child view to the aforementioned general property. This is how I tried to achieve this, but it does not work:
<UserControl x:Name="rootView"> <StackPanel> <my:ChildView DataContext="{Binding Path=SelectedChild}" EditingMode="{Binding ElementName=rootView, Path=DataContext.EditingMode /> </StackPanel> </UserControl>
Although there are no binding errors at run time, and the child view is correctly bound to the corresponding instance of the child view model, its EditingMode property EditingMode never set. I checked the tests to verify that the corresponding property of the view model will be changed, and that it notifies this change with INotifyPropertyChanged , but the binding cannot detect it.
Is there a better way to declare this binding or have I made a more basic architecture mistake?
Thanks so much for your advice,
Tim
Update: As requested, I am posting some code to show a very simplified version of my views and viewing models, as well as the results of my experiment, which may provide some additional hints.
// The relevant parts of the ParentViewModel class public class ParentViewModel : INotifyPropertyChanged { // Although not shown, the following properties // correctly participate in INotifyPropertyChanged public ChildViewModel SelectedChild { get; private set; } public ContentEditingMode EditingMode { get; private set; } } // The relevant parts of the ChildViewModel class public class ChildViewModel : INotifyPropertyChanged { // No properties of ChildViewModel affect this issue. } // The relevant parts of the ParentView class public partial class ParentView : UserControl { // No properties of ParentView affect this issue. } // The relevant members of the ChildView class public partial class ChildView : UserControl { public static readonly DependencyProperty EditingModeProperty = DependencyProperty.Register( "EditingMode", typeof(ContentEditingMode), typeof(PostView) ); public ContentEditingMode EditingMode { get { return (ContentEditingMode)GetValue(EditingModeProperty); } set { SetValue(EditingModeProperty, value); } } } // The enumeration used for the EditingMode property public enum ContentEditingMode { Html, WYSYWIG }
My intention is that the ParentViewModel will be assigned to the DataContext parent view instance, and it will in turn assign the value of its SelectedChild property to the DataContext nested ChildView . All this works correctly, but the problem arises because the binding between ParentViewModel.EditingMode and ChildView.EditingMode does not work.
In an attempt to check if there is a problem with my binding expression, I entered a TextBlock next to ChildView and linked it similarly to the ParentViewModel.EditingMode property:
<UserControl x:Name="rootView"> <StackPanel> <TextBlock Text="{Binding ElementName=rootView, Path=DataContext.EditingMode}" /> <my:ChildView DataContext="{Binding Path=SelectedChild}" EditingMode="{Binding ElementName=rootView, Path=DataContext.EditingMode /> </StackPanel> </UserControl>
In this test, the TextBlock updated correctly every time the source property changes. However, if I set a breakpoint on the ChildView.EditingMode setter, it never hits.
I am puzzled!