WPF ContextMenu woes: How do I set the DataContext of the ContextMenu?

Ashley Grenon picture Ashley Grenon · Feb 22, 2013 · Viewed 31.2k times · Source

I am having some trouble figuring out how to set the correct DataContext on a ContextMenu.

I have a collection of view models who are the source of an ItemsControl. Each view model has a collection of items which are also the source of another ItemsControl. Each item is used to draw image which has a ContextMenu. The MenuItems in that ContextMenu need to bind to a command on the view model, but the PlacementTarget of the ContextMenu is pointing to the individual item.

My Xaml looks something like this:

<ItemsControl ItemsSource="{Binding Markers"}>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ItemsControl ItemsSource="{Binding Items}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Image>
                            <Image.ContextMenu>
                                <ContextMenu>
                                     <MenuItem Header="Edit" Command="{Binding EditCommand}" />
                                </ContextMenu>
                            </Image.ContextMenu>
                        </Image>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

How can I set the DataContext of the ContextMenu to the item's corresponding parent view model?

Answer

kevindaub picture kevindaub · Feb 22, 2013

The ContextMenu is outside of the visual tree. Below is the xaml that should get you the datacontext:

<ItemsControl ItemsSource="{Binding Markers}" Tag="{Binding ElementName=outerControl, Path=DataContext}">
   ...
   <ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
      <MenuItem Header="Edit"
                Command="{Binding EditCommand}" />
   </ContextMenu>
   ...
</ItemsControl>

This post explains how this works.