Using the parent's DataContext (WPF - Dynamic Menu Command Binding)

Jesus Rodriguez picture Jesus Rodriguez · Jun 15, 2009 · Viewed 43.3k times · Source

I looked over this web and google and the solutions didn't work for me.

I have a command on the ViewModel of a UserControl. Well, The usercontrol have a ItemsControl binded to a ObservableCollection. Inside the DataTemplate of the ItemsControl.ItemTemplate I have a button and I want to use the command. I can't bind the command because inside the DataTemplate, the datacontext is not the ViewModel but an item of the ObservableCollection.

The question is: How can I bind the button to the command if a lost the parent datacontext?

I think that this need to have an easy solution because I think that this is a common problem.

Imagine this sceneario:

You have a ListBox item with an observableCollection as the ItemsSource, so you are using a datatemplate inside the ListBox for every element in the collection. Well, you want to delete the selected item and you put a button in every row for that job. ¿How do you do that?

In MVP, I can do this in the click event of the button:

Button but = e.Source as Button;

if (but != null)
      Presenter.ActualNote = but.DataContext as Note;

In short. You send the datacontext of the row (the selected item) to the presenter.

But, how can I do it in the mvvm way? Because I need to use a command but I can't assign the command to the button because the button does know nothing about the ViewModel (where the command exists).

As you can see, the button has to exist inside the datatemplate, then the datacontext is not the ViewModel anymore.... There is why I need to access to the parent's DataContext, for access to the command.

I hope that you understand my problem better.

Thank you.

Answer

Eddie Deyo picture Eddie Deyo · Jun 15, 2009

Use the binding below for your button's command:

{Binding DataContext.CommandName, 
         RelativeSource={RelativeSource FindAncestor, 
                         AncestorType={x:Type MyUserControl}}}

This will tell it to find your UserControl and use its DataContext.