Reputation: 5019
I am trying to bind the ContextMenu to ViewModel's commands. After some online search, I learned that since ContextMenu doesn't belong to the target visual tree, I need to specify the DataContext of ContextMenu explicitly using for example, Tag and PlacementTarget.Tag. The UIElement I am attaching the ContextMenu to is a WindowsFormsHost. I don't know whether that's a problem, I will explain why I said that later. My xaml looks like this:
<WindowsFormsHost Name="myHost1" Tag="{Binding DataContext, RelativeSource={RelativeSource Mode=Self}}">
<WindowsFormsHost.ContextMenu>
<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}" x:Name="test">
<MenuItem Header="Save" Command="{Binding SaveCommand}" />
...
But this code just simply doesn't work.
I put some names to the UIElements so I can check them in the code-behind. And here is what I found: myHost1.Tag
is correctly assigned to my ViewModel, which has the correct command. However, the DataContext
of my ContextMenu object is nothing which means my second binding doesn't work. Then when I checked test.PlacementTarget
, I surprisingly found out that it is nothing. No wonder the second binding doesn't work.
According to MSDN, the PlacementTarget
property is "UIElement relative to which the ContextMenu is positioned when it opens." So to my understanding when I check test.PlacementTarget
, it should return myHost1 which is of type WindowsFormsHost
. But why it is nothing?
I said I don't know whether WindowsFormsHost
is special, since it holds some WindowsFom controls which are rendered differently than WPF. For example, myHost1
is actually hosting a AxPivotTable
which has its own context menu. I had to do some extra work to make my WPF context menu visible and hide AxPivotTable
context menu. On the other hand, when I put a ContextMenu object to the parent of myHost1, which is a StackPanel
, the PlacementTarget
is still nothing, which seems to suggest it is not WindowsFormsHost's problem.
Upvotes: 3
Views: 1554
Reputation: 20461
Why not try a different approach, and have your DataContext
for your whole window as a StaticResource
in your Windows.Resources. Then your command binding would look like this:
<MenuItem Header="Save"
Command="{Binding Source={StaticResource MainViewModel}, Path=SaveCommand}" />
Upvotes: 1