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

时间:2012-04-17 06:38:15

标签: wpf keyup routedevent

问题:

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

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

    <Grid KeyUp="Grid_KeyUp">
        <Button Click="Button_Click"></Button>
    </Grid>
    

    代码隐藏:

    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");
        }
    }
    

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

    KEYUP: Return
    

    奇怪的事实:

    1. 按[Escape](KEYUP: Escape打印)时会出现相同的行为,但是当我按[Space]时,控制台不打印任何内容!
    2. e.Source和e.OriginalSource指向主窗口中的按钮(显然是错误的)。
    3. 如果您在MessageBox.Show(...)之后立即设置断点,则事件不会被KeyUp处理程序处理(即输出为空)。
    4. 有人可以向我解释发生了什么吗?

      PS Target框架是:.NET 4 Client

1 个答案:

答案 0 :(得分:4)

显然,当您按下回车键或转义符时,消息框将关闭, 会在您抬起按钮之前MainWindow获得焦点并抓住KeyPress

空格键没有发生这种情况的原因是,按空格键会按下按钮 ,但在您自行释放空格键之前不会释放它 。这意味着在按钮“未按下”之前释放空格键,因此MessageBox仅在空格键释放后才会关闭,因此MainWindow不会按下按钮。

您可以通过按住空格键来测试。 您将看到该按钮被按下但在您释放按钮之前未按下该按钮。

你可以在MessageBox关闭后创建一个标志。检查它是否是第一个KeyPress(并且可能检查它是否在关闭后不到10毫秒发生)然后忽略它。

我知道,它很难看,但我认为你还有很多事情可做(如果我是对的)

相关问题