Я обнаружил, что это не работает для меня из-за вложенности пункта меню, что означает, что мне пришлось перебрать дополнительный «Родитель», чтобы найти PlacementTarget.
Лучший способ - найтисам ContextMenu как RelativeSource, а затем просто привязать его к цели размещения.Кроме того, поскольку тег является самим окном, а ваша команда находится в модели представления, вам также необходимо установить DataContext.
В результате я получил нечто подобное
<Window x:Class="Window1" ... x:Name="myWindow">
...
<Grid Tag="{Binding ElementName=myWindow}">
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding PlacementTarget.Tag.DataContext.MyCommand,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=ContextMenu}}"
Header="Test" />
</ContextMenu>
</Grid.ContextMenu>
</Grid>
</Window>
Чтоэто означает, что если у вас получится сложное контекстное меню с подменю и т. д., вам не нужно будет добавлять «родительский элемент» для команд каждого уровня.
- EDIT -
Также предложили эту альтернативу, чтобы установить тег для каждого ListBoxItem, который привязывается к Window / Usercontrol.Я закончил тем, что сделал это, потому что каждый ListBoxItem был представлен их собственной ViewModel, но мне нужно было, чтобы команды меню выполнялись через ViewModel верхнего уровня для элемента управления, но передавали их ViewModel списка в качестве параметра.
<ContextMenu x:Key="BookItemContextMenu"
Style="{StaticResource ContextMenuStyle1}">
<MenuItem Command="{Binding Parent.PlacementTarget.Tag.DataContext.DoSomethingWithBookCommand,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=ContextMenu}}"
CommandParameter="{Binding}"
Header="Do Something With Book" />
</MenuItem>>
</ContextMenu>
...
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="ContextMenu" Value="{StaticResource BookItemContextMenu}" />
<Setter Property="Tag" Value="{Binding ElementName=thisUserControl}" />
</Style>
</ListView.ItemContainerStyle>