这似乎是一个非常受欢迎的话题,但是......
我有以下 XAML:
<internal:MyCommandObject x:Name="CommandModel"/>
<Button DockPanel.Dock="Bottom" Command="{Binding DoAction, ElementName=CommandModel}">
<Button.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}">
<MenuItem Command="{Binding DoAction, ElementName=CommandModel}"/>
</ContextMenu>
</Button.ContextMenu>
Click Me
</Button>
现在,
MyCommandObject
是一个从其DataContext
公开动态命令的控件。 .你知道接下来会发生什么。 :)基本上,按钮命令完美运行 - 当我单击它时,
DoAction
MyCommandObject
上的命令得到完美执行。但是,菜单项中的命令不会被执行。我尝试了各种技巧,例如设置上下文菜单 datacontext
成为placementTarget
所以它可以遍历控件的可视化树等等,但是什么也没做。RelativeSource
的特殊对齐方式和 CommandTarget
rune 我需要让它工作吗?
最佳答案
发生这种情况是因为 DataContext="{Binding PlacementTarget,...
绑定(bind)会将按钮设置为 MenuItems DataContext
但这不会添加 ContextMenu
到你窗口的 VisualTree 这就是为什么 ElementName
绑定(bind)不起作用。使用的简单解决方法ElementName
bindings 是将其添加到您的 Window/UserControl 的代码隐藏中:
NameScope.SetNameScope(contextMenuName, NameScope.GetNameScope(this));
另一个解决方案是这样做 -
<ContextMenu DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}">
<MenuItem Command="{Binding DataContext.DoAction}"/>
</ContextMenu>
DataContext="{Binding PlacementTarget,...
将 Button(Placementtarget) 设置为 ContextMenu 的 DataContext,因此您可以使用 Button 的 DataContext 来绑定(bind)命令。更新:
您可以尝试使用
NameScope.NameScope
Attached Property在 XAML 中设置 NameScope 但我不确定如何在没有代码的情况下获得父窗口的 NameScope!您将不得不执行类似于 Josh Smith 的以下文章的操作,他提供了一种在 XAML 中执行此操作的方法;但这也涉及代码(不仅仅是那一行代码)-
Enable ElementName Bindings with ElementSpy
有什么不使用这行代码的具体原因吗?
关于wpf - 如何通过可视化树从 ContextMenu menuitem 访问控件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11333028/