使用 OnKeyUp 在 TextBox 中按下 Enter 时避免 Windows 'Ding'
Posted
技术标签:
【中文标题】使用 OnKeyUp 在 TextBox 中按下 Enter 时避免 Windows \'Ding\'【英文标题】:Avoid Windows 'Ding' when Enter is pressed in TextBox with OnKeyUp使用 OnKeyUp 在 TextBox 中按下 Enter 时避免 Windows 'Ding' 【发布时间】:2011-07-12 07:23:46 【问题描述】:如果用户在带有 KeyUp 事件的 Windows 窗体文本框中按 Enter 键,Windows 会发出 哔声或叮叮声。我无法确定为什么会发生这种情况以及如何避免这种情况。
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:消除声音的实际解决方案:
private void TextBox_KeyDown(object sender, KeyEventArgs e)
if (e.KeyCode == Keys.Enter)
e.SuppressKeyPress = true;
【讨论】:
【参考方案2】:我想这是由以下因素的组合引起的:
MultiLine = false
表单上没有默认按钮
因为单行文本框将回车键转发到默认按钮。找不到默认按钮时会生成 ding。
【讨论】:
现在我明白了。我检查了一下。使用 MultiLine=false:如果我在表单接受按钮中设置此按钮,它会立即被激活。所以没有 ding,但我还有很多其他按钮,这不是我的接受按钮。如果我设置 MultiLine=true ,那么叮当声也消失了。这是我更喜欢的,另外 WordWrap=false。感谢您的帮助。【参考方案3】:以下是实际答案:
Private Sub myTextBox_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles myTextBox.KeyPress
If Asc(e.KeyChar) = 13 Then
e.Handled = True
End If
End Sub
这会吃掉按键,从而防止叮当声。
【讨论】:
【参考方案4】:在寻找解决方案几个小时后,我得到了一个解决方法,但不是这个问题的真正解决方案。现在我改用 KeyDown。
private void tbSearch_KeyDown( object sender, KeyEventArgs e )
if ( e.KeyCode == Keys.Enter )
e.Handled = true;
// Call Button event
//btnSearch_Click( sender, EventArgs.Empty );
// cleaner code. Thanks to Hans.
btnSearch.PerformClick();
还有一个对所有开发人员有用的建议:不要用静音测试您的应用程序。 ;-)
【讨论】:
覆盖 ProcessCmdKey() ,以便它可以工作任何具有焦点的控件。当您识别 Keys.Enter 时返回 true 以避免叮当声。您可以使用 Button.PerformClick() 顺便说一句。 Button.PerformClick() 是一个好点。我不知道。但是 ProcessCmdKey 会使我的工作复杂化,因为我有很多按钮和文本框。我总是需要检查谁是发件人。我正在使用 ProcessDialogKey 方法来处理一些全局键事件,例如 F3 用于保存,F1 用于帮助...【参考方案5】:以上解决方案都不适合我……但这是我的简单解决方案! 它仅在您不再需要应用中的接受按钮时才有效。
private void txtPassword_KeyDown(object sender, KeyEventArgs e)
if (e.KeyCode == Keys.Enter) cmdLogin.PerformClick();
private void txtPassword_Enter(object sender, EventArgs e)
this.Acceptbutton = this.cmdLogin;
private void txtPassword_Leave(object sender, EventArgs e)
this.Acceptbutton = Null;
这样,当按下“Enter”时,您将不会听到带有焦点的特定文本框上的 ping!
【讨论】:
【参考方案6】:当用户从单行文本框中按 Enter 键时,我从自定义控件调用 myDialog.ShowDialog() 时会发生此问题的一个版本。
(他们将产品编号放入文本框中,按回车键,然后弹出对话框并让他们从可用尺寸中进行选择。但是如果每次弹出对话框时都会播放铃声,那就太烦人了。)
我在文本框中捕获了按键事件,并设置了 e.Handled 和 e.SupressKeypress,但这并没有解决问题。然后我注意到,如果我注释掉了对 myDialog.ShowDialog() 的调用,那么我就听不到声音了,这很奇怪。在这种情况下,e.Handled 和 e.SupressKeypress 确实阻止了响铃。
我想也许事件会以某种方式传递到对话框,所以我在表单级别和表单的每个需要按键的元素上捕获了 keydown 事件,并将 e.Handled 和 e.SuppressKeypress 设置为所有这些,但这并没有解决它。
我尝试在表单上放置一个提交按钮并将表单的 AcceptButton 属性设置为该按钮,但这也没有帮助。
我尝试在调用 myDialog.ShowDialog() 之前调用 Application.DoEvents(),但这并没有解决问题。
我注意到调用 Application.DoEvents() 会导致铃声播放,即使对 myDialog.ShowDialog() 的调用被注释掉了!好像调用 DoEvents 是在处理当前事件,而不注意 e.Handled 和 e.SupressKeypress 限定符。
所以.. 我想如果我让当前事件在预选赛进行时播放,然后然后在此之后引发我的对话?
所以我将 myDialog.ShowDialog() 放入 BeginInvoke 部分(因为我的印象是调用将消息添加到主消息队列中,导致在处理该消息时调用该方法):
BeginInvoke((MethodInvoker)delegate
SelectProduct(); // <-- pops the size selection dialog
);
信不信由你,这解决了它 - 没有铃声。
(当我需要在后台线程调用回调时更新视图时,我通常使用调用,因为 WinForms 视图不允许从主线程以外的线程对其自身进行更新。)
所以我猜测单行文本框所在的自定义控件是需要接受按钮的地方 - 但自定义控件没有 AcceptButton 属性。
WinForms 编程似乎有点玄学。就像所有其他类型的编程一样,我猜。
【讨论】:
以上是关于使用 OnKeyUp 在 TextBox 中按下 Enter 时避免 Windows 'Ding'的主要内容,如果未能解决你的问题,请参考以下文章
如何防止在WinForms TextBox中按下alt键引起的哔声?
如何通过 MS-Access VBA 中的 TextBox.OnKeyUp 属性传递 KeyCode