Binding Command to Ancestor View Model from View in WPF MVVM
Half a year ago while I was working on a WPF MVVM application, I came across a situation where I had placed a view on top of another view and wanted to trigger a command defined in the underlying view's view model. Now you may be wondering why I wanted to bind to a command defined in a different (than the current view's) view model, the answer to that is pretty much architectural. We wanted to use that specific view model for that kind of logic. Using MVVM Light Toolkit by Laurent Bugnion, I thought I'd share with you how I did this. Consider View2
is placed on top of View1
, both having ViewModel2
and ViewModel1
as their respective models. The XAML code to bind and trigger the command then looks like this:
<UserControl x:Class="View1"
xmlns:V="clr-namespace:Views"
DataContext="{Binding Source={StaticResource Locator},
Path=ViewModel1}">
<V:View2>
<I:Interaction.Triggers>
<I:EventTrigger EventName="MouseDoubleClick">
<I:InvokeCommandAction Command="{Binding DataContext.MouseDownCommand,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type V:View1}}}"/>
</I:EventTrigger>
</I:Interaction.Triggers>
</V:View2>
</UserControl>
Note the binding {Binding DataContext.MouseDownCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type V:View1}}}
which makes the whole thing possible. The command is then defined as usual, in ViewModel1
:
public RelayCommand<MouseEventArgs> MouseDownCommand { get; set; }
public ViewModel1()
{
MouseDownCommand = new RelayCommand<MouseEventArgs>(OnMouseDown);
}
private void OnMouseDown(MouseEventArgs mouseEventArgs)
{
//Logic
}
And that’s it. :)