WPF中ContextMenu.PlacementTarget为空

3

我正在尝试将ContextMenu绑定到ViewModel的命令。经过一些在线搜索,我了解到由于ContextMenu不属于目标视觉树,我需要显式指定ContextMenu的DataContext,例如使用Tag和PlacementTarget.Tag。我要附加ContextMenu的UIElement是一个WindowsFormsHost。我不知道那是否是个问题,稍后我会解释为什么这样说。我的xaml如下:

<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}" />
...

但是这段代码根本不起作用。
我给UI元素命名,以便在代码后台中检查它们。这就是我发现的:`myHost1.Tag` 正确地分配给了我的ViewModel,它有正确的命令。然而,我的ContextMenu对象的 `DataContext` 为空,这意味着我的第二个绑定不起作用。然后当我检查 `test.PlacementTarget` 时,惊讶地发现它是空的。难怪第二个绑定不起作用。
根据MSDN, `PlacementTarget` 属性是“ContextMenu打开时定位的相对于其位置的UIElement”。所以据我理解,当我检查 `test.PlacementTarget` 时,它应该返回 `WindowsFormsHost` 类型的 `myHost1`。但为什么它是空的呢?
我说我不知道WindowsFormsHost是否特殊,因为它包含一些与WPF渲染方式不同的WindowsForm控件。例如,myHost1实际上托管了一个具有自己上下文菜单的AxPivotTable。我必须做一些额外的工作,使我的WPF上下文菜单可见并隐藏AxPivotTable上下文菜单。另一方面,当我把一个ContextMenu对象放到myHost1的父级StackPanel中时,PlacementTarget仍然是空的,这似乎表明这不是WindowsFormsHost的问题。
1个回答

1
为什么不尝试一种不同的方法,将您整个窗口的DataContext作为Windows.Resources中的StaticResource。然后您的命令绑定将如下所示:
<MenuItem Header="Save" 
        Command="{Binding Source={StaticResource MainViewModel}, Path=SaveCommand}" />

1
这里有一件事情,MainView 中并没有上下文菜单。它来自一个 UserControl,并且 ViewModel 是即时创建的。实际上,ViewModel 有继承层次结构,因此我无法将其存储为静态资源。 - tete

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接