ContextMenu действительно не является частью визуального дерева. Но я думаю, что по этой причине RelativeSource не будет работать, поскольку привязка будет искать визуальное дерево для текста данных. contextMenu не является частью этого визуального дерева, поэтому он не найдет правильный текст данных. Я нашел решение для этого в прошлом, используя прокси-элемент в ресурсах для окна. Затем установите этот прокси-элемент как контент для скрытого управления контентом в окне В menuItem установите для CommandBinding значение Datacontext.DeleteCommand, а для источника статический прокси-элемент ресурса. Это немного хакерски, но это работает.
Чтобы показать xaml, попробуйте это:
Сначала в ресурсах окна создайте элемент frameworkelement с набором данных datacontext равным тексту данных windows (viewmodel)
<Window.Resources>
<FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/>
</Window.Resources>
Затем используйте ресурс для содержимого свернутого элемента управления контентом. И установить правильную привязку к пункту меню. Примерно так:
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"/>
<ListBox x:Name="lbTest" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="#F5F5F5" Width="80" Height="60" Margin="0,5,5,5">
<Border.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete"
Command="{Binding DataContext.DeleteCommand, Source={StaticResource ProxyElement}}">
<MenuItem.Icon>
<Label FontFamily="#FontAwesome" Content="" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Border.ContextMenu>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Это должно работать. Попробуйте.