7
votes

I have a form with a single text box on it. No other controls. Whenever I type the 'Enter' key or the 'Esc' key, the form functions as I desire; but I hear that horrible Windows error sound. The code looks similar to the following...

public class EntryForm: Form
{
  public EntryForm()
  {
  }

  private void EntryTextBox_KeyUp(object sender, KeyEventArgs e)
  {
    if(e.KeyCode == Keys.Enter)
    {
      // do some stuff
      Hide(); // I've also used DialogResult = DialogResult.OK here
      e.Handled = true;
    }
    else if(e.KeyCode == Keys.Escape)
    {
      Hide(); // I've also used DialogResult = DialogResult.Cancel here
      e.Handled = true;
    }
  }
}

I can 'hack' it and make the noise stop by adding the following code to the form's constructor.

AcceptButton = new Button();
CancelButton = new Button();

As I stated this causes the sound to not play, but I think this is bad form; especially since I don't need a button on the form.

Anyone know why this is the behavior and if there is a cleaner way to stop the error sound from playing?

3
If you don't have any buttons, how are you getting the dialog to form away when you hit enter or esc? A form with jus an edit control will normally just sit there when you hit enter or esc. - John Knoeller
@John Knoeller - The Hide() method hides the form. You can also set the visible property to false. If you've shown the form modally, all you have to do is set the dialog result from the code and the form will disappear. - John Kraft

3 Answers

11
votes

In the KeyDown event, set e.Handled = true and e.SuppressKeyPress = true.

8
votes

There's a more "correct" fix, one that works regardless of how many controls you have and follows the Windows Forms design model. Paste this code into your form:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
  if (keyData == Keys.Escape || keyData == Keys.Enter) {
    this.Hide();
    return true;
  }
  return base.ProcessCmdKey(ref msg, keyData);
}
2
votes

This is too long a reply to Nobugz answer to fit in a comment. If you use Nobugz code as is :

  1. the Form is going to be hidden no matter which control on the form is active and has keyboard input focus, and that is independent of whether the Form has the 'KeyPreview property set to 'true or 'false.

Here's what you need to do to make only a specific control (in this case a TextBox named 'textBox1) be hidden in the ProcessCmdKeys over-ride :

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (msg.HWnd == textBox1.Handle)
    {   
        if  (keyData == Keys.Escape || keyData == Keys.Enter)
        {
            textBox1.Hide();
            return true;
        }
    }
    return base.ProcessCmdKey(ref msg, keyData);
}

Of course if you wanted to handle the case of multiple controls needing to be hidden, you could implement a 'switch statement or whatever to test the msg.HWnd against : note I make the assumption here that all controls that could have keyboard input will have a valid HWnd.

Some memory (vague) of a situation in which I used this technique, and a text input control somehow still had keyboard input focus ... when I did not intend for it to ... makes me want to add an additional test like this :

&& this.ActiveControl == textBox1

But, take that with a "grain of salt" since I can't be certain it is necessary.