PreviewKeyDown没有看到Alt-modifiers

pax*_*blo 30 c# wpf

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

Keyboard.PreviewKeyDown="Window_PreviewKeyDown"
Run Code Online (Sandbox Code Playgroud)

子句和后备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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在工作得很好,双方CTRLLCTRLR调用相关功能.

一旦我更改了要使用的修改器检查ModifierKeys.Alt,它就会停止工作.换句话说,无论是ALTLALTR调用的函数.

我在这里错过了什么?

Ray*_*rns 52

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

Key = Key.System
SystemKey = the real key
Run Code Online (Sandbox Code Playgroud)

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

if (e.KeyboardDevice.Modifiers == ModifierKeys.Alt) {   
    switch (e.SystemKey) { 
      ...
Run Code Online (Sandbox Code Playgroud)

说明

在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键关闭时,字母会以三对事件形式出现:KeyDown,KeyUp和TextInput,每个事件都有相关的预览版本.这里的主要区别是:

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


Jul*_*ain 44

如果是Alt修饰符,则e.Key返回Key.System并且实键在e.SystemKey.您可以使用以下代码来始终获得正确的按键:

Key key = (e.Key == Key.System ? e.SystemKey : e.Key);
Run Code Online (Sandbox Code Playgroud)