ibram
ibram

Reputation: 4569

Avoid Windows 'Ding' when Enter is pressed in TextBox with OnKeyUp

If a user hits enter in a windows forms textbox with a KeyUp Event, windows sounds a beep or ding. I could not determine why this happens and how I could avoid this.

Any help would be appreciated.

Upvotes: 11

Views: 10129

Answers (6)

Shavais
Shavais

Reputation: 2586

I had a version of this problem that would happen when I called myDialog.ShowDialog() from a custom control when the user hit enter from a single line text box.

(They put a product number into a text box, hit enter, and the dialog pops and lets them select from the available sizes. But it's supper annoying if a bell sound plays every time the dialog pops.)

I trapped the key down event in the text box, and set e.Handled and e.SupressKeypress, but that didn't solve the problem. Then I noticed that if I commented out the call to myDialog.ShowDialog(), then I didn't get the sound, as weird as that is. In that case, e.Handled and e.SupressKeypress did prevent the bell.

I thought maybe the event was somehow getting passed on to the dialog, so I trapped the keydown event at the form level and on every element of the form that takes keystrokes at all, and set e.Handled and e.SuppressKeypress in every one of those, but that didn't fix it.

I tried putting a submit button on the form and setting the AcceptButton property of the form to that button, but that didn't help either.

I tried calling Application.DoEvents() before calling myDialog.ShowDialog(), but that didn't fix it.

I noticed that calling Application.DoEvents() caused the bell to play even when the call to myDialog.ShowDialog() was commented out! As if calling DoEvents was processing the current event without paying attention to the e.Handled and e.SupressKeypress qualifiers.

So.. I thought what if I let the current event play out while the qualifiers are in play, and then raise my dialog after that?

So I put myDialog.ShowDialog() into a BeginInvoke section (since my impression is that an invoke adds a message into the main message queue that causes the method to get called when that message is processed):

        BeginInvoke((MethodInvoker)delegate {
            SelectProduct(); // <-- pops the size selection dialog
        });

Believe it or not, that fixed it up - no bell.

(I commonly use invokes when I need to update the view when a background thread calls a callback, since WinForms views don't allow themselves to be updated from a thread other than the main thread.)

So I'm guessing the custom control, where the single line text box is, is where an accept button is needed - but a custom control has no AcceptButton property.

WinForms programming seems to be a bit of a black art. Just like every other kind of programming, I guess.

Upvotes: 0

Grooveman
Grooveman

Reputation: 1

None of above solutions did the job for me ... but here's my simple solution!
It works only when you have no further need for an Acceptbutton in your App.

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

In this way you won't hear the ping on the specific textbox with the focus when 'Enter' is pressed!

Upvotes: 0

Camilo Martin
Camilo Martin

Reputation: 37898

Actual solution for getting rid of the sound:

private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
    {
        e.SuppressKeyPress = true;
    }
}

Upvotes: 13

Rogala
Rogala

Reputation: 2773

Here is the actual answer:

    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

This eats the key press, which prevents the ding.

Upvotes: 5

ibram
ibram

Reputation: 4569

After some hours digging for a solution, I just got a workaround, but not a real solution for this problem. Now I'm using KeyDown instead.

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

And a useful suggestion to all developers: Don't test your applications whit mute sound. ;-)

Upvotes: 2

Ben Voigt
Ben Voigt

Reputation: 283634

I imagine this is caused by a combination of:

  • MultiLine = false
  • No default button on the form

because single-line textboxes forward the enter key to the default button. The ding is generated when a default button can't be found.

Upvotes: 10

Related Questions