【问题标题】:Stop the Enter Key from Firing on a WinForm停止在 WinForm 上触发 Enter 键
【发布时间】:2012-02-07 11:32:19
【问题描述】:

我有一个基本的自定义对话框,可用于 WinForms 应用程序中的各种控件。对话框如下所示:

出于各种原因,我不希望用户能够使用Enter 键来选择“是”选项 (buttonYes)。以前我确实想要这种行为,并相应地设置了 Yes 按钮 (buttonYes) 的 AcceptButton 属性。我已经删除了这个,将buttonYesAcceptButton 属性设置为“无”,但是当按下Enter 键时,表单仍然会触发buttonYes.Click 事件。我还尝试处理 KeyPressKeyDown 事件,但使用 Enter 键时不会触发这些事件。这是基本且烦人的,有没有人遇到过这个,我可以做些什么来实现我想要的功能?

【问题讨论】:

    标签: c# winforms dialog


    【解决方案1】:

    这里所有的答案都是错误的或强调错误。

    为了了解发生了什么,您必须了解 Form.ShowDialog(...) 基本上是如何实现的。在引擎盖下,ShowDialog 正在进入它自己的消息循环。该消息循环具有专门处理 Enter 键的硬编码逻辑。

    对话框没有关闭,因为 OK 按钮有焦点,按下回车,WinForms 执行 OK 按钮的点击逻辑,关闭窗口。对话框正在关闭,因为 Enter 按下消息正在从在调用堆栈顶部运行的消息循环中提取出来,被消耗,并导致 ShowDialog 打破其循环并关闭窗口......所以你可以'无法通过处理按钮上的按键事件来获得您想要的功能; Enter 的按键事件永远不会被调度。通过 KeyPreview 的事件只是获取相同事件的另一种方式,因此这也无济于事。

    唯一可行的方法是将表单的 AcceptButton 属性设置为(无)。 OK 按钮仍然可以将其 DialogResult 属性设置为 OK,因此这样做不会破坏对话框,但如果 AcceptButton 设置为 none,WinForms 只会忽略 ShowDialog 中的 Enter 单击。

    【讨论】:

    • 这是正确答案!! (jwezorek,我在您的答案中添加了一张图片,以便人们更轻松地查看和消化)希望,它最终会得到超出“接受”的错误答案,:-)
    • 即使我的回答得到了更高的评价,我相信这是正确的方法。
    • 正确答案,附带说明,如果您的表单有一个内部带有 WPF 控件的 ElementHost,则该控件需要有自己的按钮“IsDefault”= false,否则您会得到相同的行为。
    【解决方案2】:

    要解决此问题,请将 TabStop 属性设置为 False 并使用以下代码:

    private void form1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
    {
        if (e.KeyChar == (char)Keys.Enter)
            e.Handled = true;
    }
    

    或者,如果如您所说,您无法在 KeyPressEvent 处中断,则需要处理 ProcessKeyPreview

    protected override bool ProcessKeyPreview(ref System.Windows.Forms.Message m)
    {
        int _ENTER = 13;
    
        if (m.Msg == _ENTER)
        {
            //Do nothing
        }
        return base.ProcessKeyPreview(ref m);
    }
    

    【讨论】:

    • 感谢您的回答。一件事:KeyPress 事件的委托不包含参数KeyEventArg 的定义。相反,它将是KeyPressEventArg,代码将是if (e.KeyChar == (char)Keys.Enter) e.Handled = true;。再次感谢您的宝贵时间。
    • 这些方法都没有奏效(我之前尝试过第一种)。我对第二个抱有希望,但这也没有被解雇。我对此感到困惑......
    • @Killercam:感谢您的更正。您的表单 KeyPreview 属性是否设置为 true,如果没有,请设置它。
    • 我也试过了。上面的overridden 事件不会触发。
    • @Killercam:如果它放在对话框cs文件的代码隐藏中,它必须触发。确保您没有将它放在调用对话框的文件中。
    【解决方案3】:

    另外,如果您想确保用户必须点击按钮而不是使用键盘,您可以将按钮上的TabStop 属性设置为False

    【讨论】:

    • 这与问题无关。
    • 为什么不呢?他不希望用户使用 Enter 键来选择按钮。如果他将按钮上的 TabStop 设置为 false,他甚至不需要关心按下的键。
    • Tabstop 不只影响 TabStop 吗? Tabstop 与 Enter 有什么关系?
    • Enter 键只是提交按钮,因为它具有焦点。如果按钮从未获得焦点,则无法由键盘触发。
    • 事件将在那里,您无需编写任何代码来处理它,因为它不会按下按钮,因为它们没有焦点。
    【解决方案4】:

    既然您已经更改了 Accpet 按钮属性:那么表单的 KeyPreview 属性呢?它设置为假还是真?也许您在途中的某个地方将其设置为 true 并忘记了它。 将其设置为 false。

    【讨论】:

      【解决方案5】:

      我只需要处理这个问题,提供的解决方案都不起作用,所以我处理 Click 事件,例如:

      private void yes_Click( object sender, EventArgs e )
      {
          if( e.Equals( EventArgs.Empty ) )
              return;  // ignore "Enter" key press
      
          // process mouse click...
      }
      

      【讨论】:

        【解决方案6】:

        您应该查看 *.resx 或 *.ressources 文件。 搜索 AcceptButton 属性。它可能已在这些文件之一中设置。

        【讨论】:

        • 他为什么要看他们?
        • 在这些文件中设置了一些属性。他应该澄清没有设置任何这些属性。
        猜你喜欢
        • 2022-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-23
        • 2014-02-09
        • 1970-01-01
        • 2014-10-27
        相关资源
        最近更新 更多