【问题标题】:KeyUp processed for wrong controlKeyUp 处理错误控制
【发布时间】:2010-03-23 13:40:22
【问题描述】:

我为这个问题制作了一个简单的测试应用程序,两个 winform,每个包含一个按钮。 单击第一个表单上的按钮会打开另一个表单。它还订阅 keyup 事件。

第二个表单的按钮设置为“AcceptButton”,在 Clicked 事件中我们休眠 1s,然后将 DialogResult 设置为 true(休眠是为了模拟一些处理完成)

当使用 enter 关闭第二个表单时,第一个表单上的按钮的 KeyUp 事件会被触发,即使在第二个表单通过之前很久就释放了键,所以第二个表单仍然显示并聚焦。

如果在第二个表单中按下除 enter 之外的任何键,则不会为第一个表单上的按钮触发事件。

第一种形式:

    public Form1()
    {
        InitializeComponent();
        buttonForm2.KeyUp += new KeyEventHandler(cntKeyUp);
    }

    void cntKeyUp(object sender, KeyEventArgs e)
    {
        MessageBox.Show(e.KeyCode.ToString());
    }

    private void buttonForm2_Click(object sender, EventArgs e)
    {
        using (Form2 f = new Form2())
        {
            f.ShowDialog();
        }
    }

第二种形式:

    private void button1_Click(object sender, EventArgs e)
    {
        Thread.Sleep(1000);
        this.DialogResult = DialogResult.OK;
    }

有谁知道为什么会为非活动表单上的按钮触发事件以及如何阻止这种情况发生?

【问题讨论】:

  • 通过在Form1中添加一个KeyDown处理程序解决了问题,然后keyup事件验证EventArgs的KeyValue是否与KeyDown设置的匹配,然后将其清除。如果 KeyUp 事件由另一个对话框触发,则永远不会设置 KeyDown 值,我们知道不应该采取任何行动。按照 SLaks 的建议,以第二种形式调用是小型测试用例中的一种潜在解决方案,但在实际应用中,很容易忘记在一个或多个对话框中执行此操作。

标签: c#


【解决方案1】:

在发送WM_KEYUP 消息之前,您正在进行阻塞调用,然后关闭表单。

在发送消息时,第二个表单已经消失,因此当前焦点控制在第一个表单上。

您可以通过在第二个表单的点击处理程序中调用 BeginInvoke 来解决此问题,仅在下一个消息循环中隐藏表单(在 KeyUp 之后)

【讨论】:

    【解决方案2】:

    一种方法:

    您可以在 cntKeyUp 中验证发件人是否是您期望的表单然后处理它,否则忽略。

    【讨论】:

    • 发件人是Form1上的按钮,换句话说就是我有兴趣听的那个。所以这行不通。
    猜你喜欢
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多