PreviewKeyDown没有看到Alt-modifiers

我有一些(应该是)捕获击键的代码。 顶层窗口有一个

Keyboard.PreviewKeyDown="Window_PreviewKeyDown" 

子句和支持CS文件包含:

 private void Window_PreviewKeyDown(object sender, KeyEventArgs e) { if (e.KeyboardDevice.Modifiers == ModifierKeys.Control) { switch (e.Key) { case Key.L: btnPrev_Click(sender, new RoutedEventArgs()); e.Handled = true; break; case Key.R: btnNext_Click(sender, new RoutedEventArgs()); e.Handled = true; break; } } } 

现在工作正常, CTRL LCTRL R都调用相关函数。

一旦我将modifer check更改为使用ModifierKeys.Alt ,它就会停止工作。 换句话说, ALT LALT R都不会调用这些函数。

我在这里想念的是什么?

Alt修饰符的情况下, e.Key返回Key.System ,真实键在e.SystemKey 。 您可以使用以下代码来始终获得正确的按键:

 Key key = (e.Key == Key.System ? e.SystemKey : e.Key); 

麻烦的是当按下Alt时你的KeyEventArgs有:

 Key = Key.System SystemKey = the real key 

因此,在检查Alt时,您需要使用e.SystemKey而不是e.Key,如下所示:

 if (e.KeyboardDevice.Modifiers == ModifierKeys.Alt) { switch (e.SystemKey) { ... 

说明

在Windows下,“Alt”键是专门处理的。 按住Alt键本身或按住Alt键时按下其他键,将其视为“系统”按键。 在许多方面,“系统”按键的处理方式与常规按键的处理方式不同。

这一切都始于Windows将按键传递给您的应用程序。 正常按键事件会生成WM_KEYDOWN,但如果按下Alt键,则会生成WM_SYSKEYDOWN。 同样,WM_KEYUP被转换为WM_SYSKEYUP。

在整个Windows中,包括在WPF中,Alt键的特殊处理与MenuItems,Buttons和Labels一起使用,包括“访问文本”。 例如,如果按钮的内容为“Say _Hi”,则按下Alt-H将被视为按钮单击。

当Alt键关闭时,字母会以三对事件forms出现:KeyDown,KeyUp和TextInput,每个事件都有相关的预览版本。 这里的主要区别是:

  • KeyDown和KeyUp事件将其Key属性设置为“Key.System”而不是按下的实际键,并将SystemKey设置为按下的实际键。
  • TextInput事件正常传递,但如果未使用则作为AccessKey处理