如何通过可视化树从 ContextMenu 菜单项访问控件? [英] How to access a control from a ContextMenu menuitem via the visual tree?

查看:26
本文介绍了如何通过可视化树从 ContextMenu 菜单项访问控件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这似乎是一个很受欢迎的话题,但是...

This seems to be a pretty popular topic, but...

我有以下 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 公开动态命令的控件.你知道接下来会发生什么.:)

Now, MyCommandObject is a control which exposes dynamic commands from its DataContext. You know what's coming next. :)

基本上,按钮命令完美运行 - 当我单击它时,MyCommandObject 上的 DoAction 命令得到完美执行.但是,菜单项中的命令不会被执行.我尝试了各种技巧,例如将上下文菜单 datacontext 设置为 placementTarget 以便它可以遍历控件的可视化树等,但什么也没做.

Basically, the button command works perfectly - when I click it, the DoAction command on the MyCommandObject gets executed perfectly. However, the command in the menuitem doesn't get executed. I've tried various tricks such as setting the context menu datacontext to be the placementTarget so it can traverse the visual tree of the controls and so on, but nothing's doing.

我需要RelativeSourceCommandTarget 符文的什么特定对齐才能使其工作?

What particular alignment of RelativeSource and CommandTarget runes do I need to get this to work?

推荐答案

发生这种情况是因为 DataContext="{Binding PlacementTarget,... 绑定会将按钮设置为 MenuItems DataContext 但这不会将 ContextMenu 添加到窗口的 VisualTree,这就是 ElementName 绑定不起作用的原因.使用 ElementName 的简单解决方法 绑定是在你的 Window/UserControl 的代码隐藏中添加这个:

This is happening because DataContext="{Binding PlacementTarget,... binding would set the button as MenuItems DataContext but that won't add the ContextMenu to the VisualTree of your window and that's why ElementName binding's won't work. A simple workaround to use ElementName bindings is to add this in your Window/UserControl's code-behind:

NameScope.SetNameScope(contextMenuName, NameScope.GetNameScope(this)); 

另一种解决方案是这样做 -

Another solution is to do this -

<ContextMenu DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}">   
    <MenuItem Command="{Binding DataContext.DoAction}"/>   
</ContextMenu>

DataContext="{Binding PlacementTarget,... 会将 Button(Placementtarget) 设置为您的 ContextMenu 的 DataContext,因此您可以使用 Button 的 DataContext 来绑定命令.

DataContext="{Binding PlacementTarget,... will set the Button(Placementtarget) as the DataContext of your ContextMenu, so you can use Button's DataContext to bind command.

更新:

您可以尝试使用 NameScope.NameScope附加属性在 XAML 中设置 NameScope 但我不确定如何在没有代码的情况下获得父窗口的 NameScope!

You can try and use the NameScope.NameScope Attached Property to set NameScope in XAML but I am not sure how you will get the NameScope of parent window without code!

您必须执行类似于 Josh Smith 的以下文章的操作,他提供了一种在 XAML 中执行此操作的方法;但这也涉及代码(不仅仅是那一行代码)-

You will have to do something similar to following article by Josh Smith, he provides a way to do this in XAML; but that too involves code (more then that single line of code) -

使用 ElementSpy 启用 ElementName 绑定

不使用这行代码的任何具体原因?

Any specific reason to not use this single line of code?

这篇关于如何通过可视化树从 ContextMenu 菜单项访问控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆