在单击任何按钮之前,将禁用上下文菜单中的WPF自定义命令

Vit*_*lij 18 wpf command

我有一个自定义命令,我尝试从上下文菜单执行它们,但它们总是显示为禁用,除非我单击UI上的任何按钮(按钮与命令没有任何关系).

单击按钮后,命令开始正确显示(当它们不可用时,它们将被禁用并启用(如果可用)).

编辑:事实证明,它不是按钮单击,这使命令正常工作,但按钮或其他控件处于焦点(例如,如果我选中控件,这也启用我的命令).

这是命令的代码:

<Window.InputBindings>
    <KeyBinding Command="{x:Static local:MainWindow.Quit}" Key="Q" Modifiers="Ctrl"/>
    <KeyBinding Command="{x:Static local:MainWindow.Disconnect}" Key="D" Modifiers="Ctrl"/>
</Window.InputBindings>

<Window.ContextMenu>
    <ContextMenu Opacity="95">
        <MenuItem Header="Quit Application                  Ctrl + Q"   Command="{x:Static local:MainWindow.Quit}"/>
        <MenuItem Header="Disconnect from the pump   Ctrl + D" Command="{x:Static local:MainWindow.Disconnect}"/>
    </ContextMenu>
</Window.ContextMenu>
Run Code Online (Sandbox Code Playgroud)

这是命令CanExecuteMethod:

public static RoutedCommand Quit = new RoutedCommand();   

private void QuitCanExecute(object sender, CanExecuteRoutedEventArgs e)
     {
      e.CanExecute = true;
      e.Handled = true;
     }
Run Code Online (Sandbox Code Playgroud)

小智 23

此问题是由于ContextMenu位于与Window及其控件的单独的Visual和Logical树上.

对于仍然在寻找这个问题的答案的人 - 在浏览互联网之后,我发现最有效的答案是在菜单项的任何声明中包含以下内容,需要其命令被其"所有者"听到.

用外行人的话说; 如果你想通过你正确点击的东西听到你的上下文菜单的命令.添加此代码:

CommandTarget="{Binding Path=PlacementTarget,
                        RelativeSource={RelativeSource AncestorType=ContextMenu}
               }"
Run Code Online (Sandbox Code Playgroud)

例:

    <ContextMenu>
        <MenuItem Header="Close" Command="Application.Close"
                  CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
    </ContextMenu>
Run Code Online (Sandbox Code Playgroud)

这也适用于模板(我发现很多其他解决方案不支持).以下是对其他地方声明的含义的解释(我在解释事情时骇人听闻):

每个FrameworkElement都有一个DataContext,它是一个任意对象.数据绑定的默认源是DataContext.您可以使用RelativeSource.Self来更改绑定到FrameworkElement本身而不是其DataContext的源.因此,RelativeSource部分只是将您从FrameworkElement的DataContext"上升一级"移动到FrameworkElement本身.进入FrameworkElement后,您可以指定其任何属性的路径.如果FrameworkElement是Popup,它将具有PlacementTarget属性,该属性是Popup相对于其定位的另一个FrameworkElement.

简而言之,如果你有一个相对于TextBox放置的Popup,那么该表达式将Popup的DataContext设置为TextBox,结果Popped正文中的某个地方{Binding Text}将绑定到TextBox的文本.

老实说,我希望这些信息可以帮助那些刚接触WPF的人,这个周末我经历过的头痛......虽然它确实教会了我很多!


Sim*_* D. 12

完全不同的轨道,现在:ContextMenu确实有一些特殊的东西作为命令的载体:菜单不被视为窗口的一部分,因此它的行为不像它的可视树中的元素.

这里定义的问题有不同的解决方案:http: //www.wpftutorial.net/RoutedCommandsInContextMenu.html

最简单的方法似乎是将此添加到您的XAML(对于窗口):

FocusManager.FocusedElement="{Binding RelativeSource={x:Static RelativeSource.Self}, Mode=OneTime}"
Run Code Online (Sandbox Code Playgroud)