Home > Enterprise >  WPF MVVM Binding to parent view's ViewModel property
WPF MVVM Binding to parent view's ViewModel property

Time:09-21

I have two views:

  • ShellView - DataContext: ShellViewModel
  • VolumeViewerView - DataContext: VolumeViewerViewModel

ShellView is the root in my program and it contains 3 VolumeViewerView objects (using their ViewModel instances).

Within each context, things run pretty smooth and as expected.

However, in the VolumeViewerView, I have an <Image> whose Cursor I'd like to control from the ShellViewModel.

Here is the code:

ShellView.xaml - MainView is an instance of VolumeViewerViewModel

<Frame  Grid.Row="1" Grid.Column="0" Grid.RowSpan="3" Content="{Binding MainView}"/>

ShellViewModel.cs

private Cursor _editorCursor;
public Cursor EditorCursor
{
    get { return _editorCursor; }
    set
    {
        _editorCursor = value;
        NotifyOfPropertyChange(() => EditorCursor);
    }
}

VolumeViewerView.xaml

<Image [OTHER PROPERTIES] 
    Cursor="{Binding Path=DataContext.EditorCursor, 
                     RelativeSource={RelativeSource Mode=FindAncestor, 
                                     AncestorType={x:Type local:ShellView}}}"/>

When I bind the Cursor to a property in VolumeViewerViewModel things work well as expected. But here it isn't connecting.

I've looked for answers here, here, and here. But none of them is working.

I wonder, is this even possible given they are in different files? Does FindAncestor only work within the context of the same xaml file?

If it isn't possible, what is a good alternative? I can create EditorCursor inside VolumeViewerViewModel and have it set every time the EditorCursor in ShellViewModel is set, but that looks a bit ugly. If it is the only way, I may just elect to go there. But I would really love suggestions!

CodePudding user response:

As @Clemens indicated in the comments, the Visual Tree ends with a Frame element. This was the root of my issues. I had put the child view in a Frame which meant FindAncestor was incapable of finding the parent element and its DataContext.

I edited ShellView.xaml, replaced Frame:

<ContentControl  Grid.Row="1" Grid.Column="0" Grid.RowSpan="3" Content="{Binding MainView}"/>

This meant that I also had to edit the child view (it originally inherited Page which cannot be the content of a ContentControl). I made it UserControl and the binding worked as expected.

  • Related