当我执行输入手势时,为什么不设置MenuItem.InputGestureText会导致MenuItem激活?

我想为MenuItem实现键盘快捷键。 我使用过以下代码:

     ` 

但是当我按下CTRL+N时, InputGestureText属性没有响应。 我正在使用Visual Studio Express Edition 2010.我在这里遗漏了什么吗?

该属性的文档中非常明确:

此属性不会将输入手势与菜单项相关联; 它只是将文本添加到菜单项。 应用程序必须处理用户的输入以执行操作。 有关如何将命令与菜单项关联的信息,请参阅命令 。

执行此操作的最佳方法是创建一个Command ,并将InputGesture与该命令相关联:

 public static class Commands { public static readonly RoutedCommand CreateNew = new RoutedCommand("New", typeof(Commands)); static Commands() { SomeCommand.InputGestures.Add(new KeyGesture(Key.N, ModifierKeys.Control)); } } ... // Wherever you want to create the MenuItem. "local" should be the namespace that // you delcared "Commands" in.  ... // Wherever you want to process the command. I am assuming you want to do it in your // main window, but you can do it anywhere in the route between your main window and // the menu item.   Executed="CreateNew_Executed" />  ... // In the code behind for your main window (or whichever file you put the above XAML in) private void CreateNew(object sender, ExecutedRoutedEventArgs e) { ... } 

如果您真的只想要一个“新”命令,则可以跳过创建RoutedCommandInputGesture ,因为已经为您创建了该命令:

  ...    ... private void New_Executed(object sender, ExecutedRoutedEventArgs e) { ... } 

一个不涉及命令和绑定的解决方案是覆盖拥有Window的OnKeyDown方法并搜索具有与键盘事件匹配的KeyGesture的菜单项。

这是Window的OnKeyDown覆盖的代码:

 protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); // here I suppose the window's menu is named "MainMenu" MainMenu.RaiseMenuItemClickOnKeyGesture(e); } 

以下是将菜单项与键盘事件匹配的实用程序代码:

  public static void RaiseMenuItemClickOnKeyGesture(this ItemsControl control, KeyEventArgs args) => RaiseMenuItemClickOnKeyGesture(control, args, true); public static void RaiseMenuItemClickOnKeyGesture(this ItemsControl control, KeyEventArgs args, bool throwOnError) { if (args == null) throw new ArgumentNullException(nameof(args)); if (control == null) return; var kgc = new KeyGestureConverter(); foreach (var item in control.Items.OfType()) { if (!string.IsNullOrWhiteSpace(item.InputGestureText)) { KeyGesture gesture = null; if (throwOnError) { gesture = kgc.ConvertFrom(item.InputGestureText) as KeyGesture; } else { try { gesture = kgc.ConvertFrom(item.InputGestureText) as KeyGesture; } catch { } } if (gesture != null && gesture.Matches(null, args)) { item.RaiseEvent(new RoutedEventArgs(MenuItem.ClickEvent)); args.Handled = true; return; } } RaiseMenuItemClickOnKeyGesture(item, args, throwOnError); if (args.Handled) return; } }