文本菜单上单击按钮没有射击指挥 [英] ContextMenu on button click not firing command

查看:104
本文介绍了文本菜单上单击按钮没有射击指挥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一个问题。

我点击一个按钮显示上下文菜单,菜单命令被绑定到ICommand的在model.Menu显示的是点击按钮以及上点右键的看法。问题是,当我点击按钮,然后单击快捷菜单,但我可以确认,菜单,工作时我的按钮,点击右键,然后单击菜单中的菜单中点击器不点火。

I am displaying context menu on a button click and the menu command is bind to ICommand in the view model.Menu is displaying on the button click as well as on the right click. The problem is menu click is not firing when I click button and then click context menu, but I can confirm that menu is working when I right click on button and then click on menu.

 <Button Grid.Row="3" Width="500" Height="30" Name="cmButton"  >
            Button with Context Menu
            <Button.ContextMenu>
                <ContextMenu DataContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Mode=Self}}"  >
                    <MenuItem  DataContext="{Binding}" Header="New Layout Element..." Command="{Binding Path=SubmitBtn}" />                  
                </ContextMenu>
            </Button.ContextMenu>
            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Style.Triggers>
                        <EventTrigger RoutedEvent="Click">
                            <EventTrigger.Actions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
                                            <DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
                                        </BooleanAnimationUsingKeyFrames>
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger.Actions>
                        </EventTrigger>
                    </Style.Triggers>                    
                </Style>
            </Button.Style>

 </Button>

我可以证实,没有什么错在我的ViewModel因为命令射击时我对上点击按钮,然后单击快捷菜单上。

I can confirm there is nothing wrong in my viewmodel because command is firing when I do right click on button then click on context menu.

推荐答案

PlacementTarget 的,当你手动设置 ContextMenu.IsOpen 属性,因为它被设置为只有一次是由目标控制右键单击打开的实际值。 ( PopUpService类负责将该值设置为实际的目标的)。

PlacementTarget is null when you manually set ContextMenu.IsOpen property because it is set to actual value only once it's open by right clicking on target control. (PopUpService class is responsible for setting this value to actual target).

由于PlacementTarget是空的情况下,当您通过Stoyboard打开它,绑定是不能够解决实际命令它绑定到。

所以,问题是你的需要在按钮的DataContext传递到菜单项,以便结合可以解决的。 (菜单项不一样的视觉树作为按钮)。可通过两种方式实现:

So, issue is you need to pass on the DataContext of button to the menu item so that binding can be resolved. (MenuItem are not is same visual tree as that of button). That can be achieved via two ways:

使用的 X:参考 (适用于WPF 4.0提供更高),但你需要声明虚拟控制,以便它可以被引用来获得DataContext的能见度设置为崩溃了。

Using x:Reference (available in WPF 4.0 and higher) but you need to declare dummy control so that it can be referenced to get DataContext with visibility set to Collapsed.

<FrameworkElement x:Name="dummyControl" Visibility="Collapsed"/>
   <Button Width="100" Height="30" Name="cmButton">
      <Button.ContextMenu>
         <ContextMenu>
           <MenuItem Header="New Layout Element..."
                     Command="{Binding Path=DataContext.SubmitBtn,
                                       Source={x:Reference dummyControl}}" />
         </ContextMenu>
      </Button.ContextMenu>
   </Button>


另一个有趣的事情是的 可冻结 对象继承DataContext的,即使他们不撒谎的VisualTree,所以我们可以利用这个特性来克服的情况下我们需要继承的DataContext。


Another interesting thing is Freezable objects inherit DataContext even if they don't lie in VisualTree so we can use this feature to overcome situations where we need to inherit DataContext.

首先,我们需要创建类从可冻结继承和揭露DP它可以绑定到:

First we need to create class inheriting from Freezable and exposing DP which can be bind to:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    public static readonly DependencyProperty DataProperty =
     DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy));
}

现在,我们可以用它在XAML是这样的:

Now we can use it in XAML like this:

    <Button Width="100" Height="30" Name="cmButton">
        <Button.Resources>
            <local:BindingProxy x:Key="proxy" Data="{Binding}"/>
        </Button.Resources>
        <Button.ContextMenu>
            <ContextMenu>
                <MenuItem Header="New Layout Element..."
                          Command="{Binding Path=Data.SubmitBtn,
                                            Source={StaticResource proxy}}" />
            </ContextMenu>
        </Button.ContextMenu>
    </Button>

这篇关于文本菜单上单击按钮没有射击指挥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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