将shorcut添加到MenuItem

时间:2015-11-24 18:09:43

标签: c# wpf gesture

我试图在我的MenuItem中添加一个shourcut:

    <Menu x:Name="menu" VerticalAlignment="Top">
        <Menu.InputBindings>
            <KeyBinding Modifiers="Control" Key="N" Command="{Binding NewTerrainCommand}" CommandParameter="{Binding ElementName=Viewport3D, Path=Camera}" />
        </Menu.InputBindings>

        <MenuItem Header="_File">
            <MenuItem Header="_New Terrain" Command="{Binding NewTerrainCommand}" CommandParameter="{Binding ElementName=Viewport3D, Path=Camera}" InputGestureText="Ctrl+N" />
        </MenuItem>
        <MenuItem Header="_Edit" />
        <MenuItem Header="_Window" />
        <MenuItem Header="_Help" />
    </Menu>

我读到这可以通过定义键绑定来完成,但这只会给我带来更多问题:

  • 我在哪里设置keybinding标签或menuitem标签中的命令,或两者都设置?
  • 如何将键绑定与menuitem相关联?

仍然无法正常工作,我很确定我错过了什么。

谢谢。

1 个答案:

答案 0 :(得分:1)

首先解释一下:

将一个命令(在本例中为RoutedCommand,或者通常和ICommand的实现)视为通过Visual树传播的各种信号。在可视树的每个元素处,WPF检查是否存在针对该命令注册的特定操作,并且如果找到一个,则执行该操作。

在您的示例中,需要声明三种不同的关联:

  1. MenuItem需要与Command
  2. 相关联
  3. 命令需要与相关操作相关联(CanExecuteExecuted
  4. MenuItem需要与Ctrl+N组合键关联。
  5. 完成(#1)非常简单 - 您只需将命令指定为MenuItem中的绑定。

    (#2)更有趣。正如我前面提到的,命令用于通过Visual树中继信号以进行操作。这意味着可视树的不同部分必须声明它们各自处理该命令的能力。该声明是通过CommandBinding进行的。 CommandBinding将一个命令与可视实体的上下文中的操作(CanExecuteExecuted相关联。

    假设执行我们的Command的方法将存在于主Window类(通常为MainWindow)中,我们需要在{{CommandBinding上指定MainWindow 1}}实例。 (更确切地说,MainWindow将是声明它处理所述命令的能力的类型之一。可以想象其他类型声明对同一Command的兴趣 - 我们的以下示例恰好只有一种表示对处理命令感兴趣的类型。

    一旦宣布了这种关联(在MainWindow和相关命令之间),每当触发Command(例如,由MenuItem)时,WPF就会知道调用已注册的CanExecute和{ {1}} Executed中的方法,因为存在相应的MainWindow来声明CommandBinding能够处理命令的事实。

    (#3)也相对容易。 MainWindow具有RoutedCommand属性,可以添加InputGestures。添加后,与此命令关联的KeyGesture将自动推断MenuItem

    以下示例(主要来自您自己的代码,经过修改)显示了这一切是如何连接在一起的:

    <强> MainWindow.xaml:

    KeyGesture

    <强> MainWindow.xaml.cs:

        <Window x:Class="CommandsSample.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:system_windows_input="clr-namespace:System.Windows.Input;assembly=PresentationCore"
            xmlns:local="clr-namespace:CommandsSample"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <!-- The following DataContext declaration simply means that the current instance of MainWindow (i.e., 'this') 
             is the operative DataContext for all data bindings specified in the rest of this XAML -->
        <Window.DataContext>
            <Binding RelativeSource="{RelativeSource Self}"/>
        </Window.DataContext>
        <Window.Resources>
            <!-- Declare a RoutedCommand with an associated KeyGesture -->
            <RoutedCommand x:Key="NewFileCommand">
                <RoutedCommand.InputGestures>
                    <system_windows_input:KeyGesture>
                        Ctrl+N
                    </system_windows_input:KeyGesture>
                </RoutedCommand.InputGestures>
            </RoutedCommand>
        </Window.Resources>
    
        <!-- The following CommandBinding associates NewFileCommand with actions defined in the code behind -->
        <Window.CommandBindings>
            <CommandBinding Command="{StaticResource NewFileCommand}" CanExecute="CouldCreateNewFile" Executed="CreatenewFile"/>
        </Window.CommandBindings>
    
        <!-- Main UI consisting of a Menu and a TextBox --> 
        <DockPanel>
            <Menu DockPanel.Dock="Top">
                <MenuItem Header="_File">
                    <!-- The New MenuItem will automatically infer the KeyGesture Ctrl+N from NewFileCommand -->
                    <MenuItem Header="_New" Command="{StaticResource NewFileCommand}" />
    
                    <MenuItem Header="_Open"/>
                    <MenuItem Header="_Save"/>
                    <Separator/>
                    <MenuItem Header="_Exit"/>
                </MenuItem>
            </Menu>
            <TextBox AcceptsReturn="True" Text="{Binding FileText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </DockPanel>
    </Window>