奇怪的 KeyUp 行为(主窗体处理来自子进程的事件?!)

Jef*_*fim 5 wpf routedevent keyup

问题:

  1. KeyUp 由主窗口中的网格处理 ( Grid_KeyUp)
  2. 主窗口显示子窗口(例如MessageBox.Show(...)
  3. 用户按 [Return] ( Keys.Return) 关闭MessageBox
  4. 主窗口实际上从 MessageBox 中的按键获取 KeyUp 事件

我有一个非常简单的孤立样本,它显示了我遇到的问题。只需创建一个空的 WPF 项目并使用此 XAML:

<Grid KeyUp="Grid_KeyUp">
    <Button Click="Button_Click"></Button>
</Grid>
Run Code Online (Sandbox Code Playgroud)

以及隐藏的代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Grid_KeyUp(object sender, KeyEventArgs e)
    {
        Console.WriteLine("KEYUP: " + e.Key);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(this, "TEST");
    }
}
Run Code Online (Sandbox Code Playgroud)

如果单击该按钮并按 [Return] 关闭 MessageBox,输出窗口将打印:

KEYUP: Return
Run Code Online (Sandbox Code Playgroud)

奇怪的事实:

  1. 当按 [Escape](打印)时,我会得到相同的行为KEYUP: Escape,但是当我按 [Space] 时,控制台不会打印任何内容!
  2. e.Source 和 e.OriginalSource 指向主窗口中的按钮(这显然是错误的)。
  3. 如果您在事件不被 KeyUp 处理程序处理之后放置断点MessageBox.Show(...)(即输出为空)。

谁能向我解释发生了什么事吗?

PS目标框架是:.NET 4 Client

Jas*_*dge 4

显然,当您按下 Enter 或 Escape 时,消息框会关闭,在您抬起按钮之前,消息框MainWindow会获得焦点并KeyPress捕获

使用空格键不会出现这种情况的原因是,按下空格键会将按钮向下推,但直到您自己释放空格键后才会释放按钮。这意味着空格键在按钮“松开”之前被释放,因此只有MessageBox在释放空格键后才会关闭,因此MainWindow不会捕获按钮按下的情况。

您可以通过按住空格键来测试这一点。 您将看到该按钮被按住,但在您释放它之前不会被按下。

您可能会创建一个在收盘后关闭的标志MessageBox。检查它是否是第一个KeyPress(也许检查它是否在关闭后 10 毫秒内发生),然后忽略它。

我知道,它很难看,但我认为你没有什么其他可以做的(如果我是对的)