4

I am new to WPF. Like many others, I am trying to bind a ContextMenu to an ObservableCollection to create a dynamic context menu. Everything works except binding the Command property to the TheCommand property of the MenuItemViewModel class, that represents the menu item. The command is not fired. What am I doing wrong?

To start from the beginning, the ContextMenu is a child of the Image and is shown when the mouse is over the Image.

 <Image.ContextMenu >
        <ContextMenu ItemsSource="{DynamicResource ContextMenu}"

where the empty ContextMenu is defined as follows:

<Window.Resources>
    <local:MenuItemViewModelCollection x:Key="ContextMenu">
    </local:MenuItemViewModelCollection>

    <HierarchicalDataTemplate DataType="{x:Type local:MenuItemViewModel}"
                                      ItemsSource="{Binding Path=Children}">
        <HierarchicalDataTemplate.ItemContainerStyle>
            <Style TargetType="MenuItem">
                <Setter Property="Command"
                    Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}},
                                    Path=DataContext.TheCommand}"/>
              <!--  Value="{Binding Path=TheCommand}" /> I tried this too -->

            </Style>
        </HierarchicalDataTemplate.ItemContainerStyle>
    </HierarchicalDataTemplate>
</Window.Resources>

The TheCommand property is defined below:

public class MenuItemViewModel : INotifyPropertyChanged
{
       //...
       public ICommand TheCommand
       {
             //...
       }
}
Nicholas Miller
  • 4,205
  • 2
  • 39
  • 62
Marianna
  • 41
  • 1
  • 2
  • What does your `MenuItemViewModelCollection` class look like? And are the menu items showing up correctly? – Rachel Nov 18 '11 at 16:42

3 Answers3

6

DataContext on ContextMenus can be weird, I bet if you look in the output window in Visual Studio when debugging that there will be a binding error for TheCommand not being found. Try the following:

<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.DataContext.TheCommand}"/> 

This will use the DataContext of the element that the ContextMenu is launched from, not the context menu itself.

Bill Reiss
  • 3,460
  • 1
  • 19
  • 20
  • This was exactly what I was trying to fix and the tip on Output window is very helpful. But I am not able to understand the hierarchy in which the DataContext is picked up. Because in my case it was picking up the content like this `Content="{Binding Heading}"` but it was not able to pick up the command `Command="{Binding DataContext.ItemSelectedCommand}"` So I had to use `Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=DataContext.ItemSelectedCommand}"` – Carbine Sep 02 '13 at 09:15
0

Look at my answer for the following question -

Context Menu items command binding WPF using MVVM

Hope it helps!

Community
  • 1
  • 1
dev27
  • 605
  • 1
  • 7
  • 15
0

Did you try

Value="{TemplateBinding TheCommand}" ?

Arsen Mkrtchyan
  • 49,896
  • 32
  • 148
  • 184