4
votes

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
       {
             //...
       }
}
3
What does your MenuItemViewModelCollection class look like? And are the menu items showing up correctly? - Rachel

3 Answers

4
votes

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.

0
votes

Did you try

Value="{TemplateBinding TheCommand}" ?

0
votes

Look at my answer for the following question -

Context Menu items command binding WPF using MVVM

Hope it helps!