Question

I would like to suppress the keyboard beep in my app, or at least while in a particular event handler. Is this possible?

UPDATE

Okay, you asked for it (code samples):

PREVIEW KEY DOWN:

    private void textBoxDuckbill_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
        switch (e.KeyCode) {
            case Keys.Down:
            case Keys.Up:
                e.IsInputKey = true;
                break;
        }
    }

KEY DOWN:

    private void textBoxDuckbill_KeyDown(object sender, KeyEventArgs e) {
        TextBox tb = (TextBox)sender;

        if (e.KeyCode.Equals(Keys.Up)) {
            SetFocusOneRowUp(tb.Name);
            e.Handled = true;
            return;
        }
        if (e.KeyCode.Equals(Keys.Down)) {
            SetFocusOneRowDown(tb.Name);
            e.Handled = true;
            return;
        }

        if (e.KeyCode.Equals(Keys.Left)) {
            SetFocusOneColumnBack(tb.Name);
            e.Handled = true;
            return;
        }
        if (e.KeyCode.Equals(Keys.Right)) {
            SetFocusOneColumnForward(tb.Name);
            e.Handled = true;
            return;
        }
    }

KEY PRESS:

    private void textBoxDuckbill_KeyPress(object sender, KeyPressEventArgs e) {
        TextBox tb = (TextBox)sender;
        errorProviderCRLogins.SetError(tb, String.Empty);

        // If user presses "%" (37) move back/left one TextBox column; 
        // if user presses "'"(39) move forward/right one TextBox column.
        // Also now allowing navigational arrows to do the same thing (KeyDown event)
        if (e.KeyChar == '%') {
            SetFocusOneColumnBack(tb.Name);
            e.Handled = true;
            return;
        }
        if (e.KeyChar == Convert.ToChar(@"'")) {
            SetFocusOneColumnForward(tb.Name);
            e.Handled = true;
            return;
        }

        // Preclude values (1,2,3) that would normally be allowed (see below) but do 
        // not have a value in the corresponding PlatypusID TextBox
        if (((e.KeyChar == '1') && (String.IsNullOrWhiteSpace(textBoxPlatypusNum1.Text))) ||
            ((e.KeyChar == '2') && (String.IsNullOrWhiteSpace(textBoxPlatypusNum2.Text))) ||
            ((e.KeyChar == '3') && (String.IsNullOrWhiteSpace(textBoxPlatypusNum3.Text)))) {
            e.Handled = true;
            return;
        }

        // Now, having gotten to here, we can assume that 1, 2, and 3 are valid (as are
        // Space and Backspace all the time).
        if ((e.KeyChar != '1') &&
            (e.KeyChar != '2') &&
            (e.KeyChar != '3') &&
            (e.KeyChar != (char)Keys.Space) &&
            (e.KeyChar != (char)Keys.Back)) {
            e.Handled = true;
            return;
        }

        // Added Space as an allowable entry so user can delete a val with that key
        // (which will automatically happen on tabbing into the TextBox, as it is
        // now being highlighted)
        if ((e.KeyChar == (char)Keys.Space) || (e.KeyChar == (char)Keys.Back)) {
            tb.Text = String.Empty;
            buttonSave.Enabled = true;
            // Don't return here, as they might continue to hit Space to zero out 
            // subsequent cells
        }

        // Now, if there is already a value in the cell (this is a repeated val, as shown
        // by TextLength being 1 instead of 0), move it to the next cell and give it the 
        // value just entered (even if space for "delete")
        if ((tb.TextLength == 1) || (e.KeyChar == (char)Keys.Space)) {
            buttonSave.Enabled = true;
            MoveToNextCellAndEnterVal(e.KeyChar.ToString(), tb.Name);
        }
        // Although KeyChar has a val such as 49/("1"), TextLength == 0
        if ((e.KeyChar == '1') ||
        (e.KeyChar == '2') ||
            (e.KeyChar == '3')) {
            buttonSave.Enabled = true;
        }
    }

TEXT CHANGED:

    private void textBoxDuckbill_TextChanged(object sender, EventArgs e) {
        TextBox tb = (TextBox)sender;

        if (tb.Text == "1") {
            tb.BackColor = PlatypusID1_BACKCOLOR;
            tb.ForeColor = PlatypusID1_FORECOLOR;
            return;
        }

        if (tb.Text == "2") {
            tb.BackColor = PlatypusID2_BACKCOLOR;
            tb.ForeColor = PlatypusID2_FORECOLOR;
            return;
        }

        if (tb.Text == "3") {
            tb.BackColor = PlatypusID3_BACKCOLOR;
            tb.ForeColor = PlatypusID3_FORECOLOR;
            return;
        }

        tb.BackColor = System.Drawing.SystemColors.Window;
        tb.ForeColor = System.Drawing.SystemColors.WindowText;
    }

    private void MoveToNextCellAndEnterVal(string APlatypusID, string ATextBoxName) {
        String numericPortionOfTextBoxName = ATextBoxName.Remove(0, LENGTH_OF_TEXT_BOX_BASE);
        String sTextBoxToFind;
        int textBoxNumber = 0;
        int nextTextBoxNumber;

        int.TryParse(numericPortionOfTextBoxName, out textBoxNumber);
        nextTextBoxNumber = ++textBoxNumber;
        // "wrap around"
        if (nextTextBoxNumber > NUMBER_OF_QUARTER_HOURS) {
            nextTextBoxNumber = nextTextBoxNumber - NUMBER_OF_QUARTER_HOURS;
        }
        sTextBoxToFind = String.Format("textBoxDuckbill{0}", nextTextBoxNumber);
        TextBox tb = (TextBox)this.Controls.Find(sTextBoxToFind, true).First();
        tb.Focus();
        tb.Text = APlatypusID;
    }

    private void SetFocusOneRowDown(string ATextBoxName) {
        String numericPortionOfTextBoxName = ATextBoxName.Remove(0, LENGTH_OF_TEXT_BOX_BASE);
        String sTextBoxToFind;
        int textBoxNumber = 0;
        int nextTextBoxNumber;

        int.TryParse(numericPortionOfTextBoxName, out textBoxNumber);
        if (!(textBoxNumber == NUMBER_OF_QUARTER_HOURS)) {
            nextTextBoxNumber = ++textBoxNumber;
        } else {
            nextTextBoxNumber = 1;
        }
        sTextBoxToFind = String.Format("textBoxDuckbill{0}", nextTextBoxNumber);
        TextBox tb = (TextBox)this.Controls.Find(sTextBoxToFind, true).First();
        tb.Focus();
    }
Was it helpful?

Solution 3

Once I changed this code at the bottom of the KeyPress event:

if ((e.KeyChar == '1') ||
    (e.KeyChar == '2') ||
    (e.KeyChar == '3')) {
    buttonSave.Enabled = true;
}

..to this:

if ((e.KeyChar == '1') ||
    (e.KeyChar == '2') ||
    (e.KeyChar == '3')) {
    buttonSave.Enabled = true;
    e.Handled = true;
    tb.Text = e.KeyChar.ToString();
}

..it works like the proverbial charm bracelet. IOW, I had to tell it to NOT allow the key to be entered (although it was valid), and then put it there programatically.

Why this works or "has to be this way" I don't know, but it works, so I'm more-or-less satisfied.

OTHER TIPS

You have to set the key as handled.

    e.Handled = true

or in some cases:

    e.SuppressKeyPress = true

Edit: Never mind, OP has stated it's not an invalid key press beep.

I did a little digging in ReSharper through the .NET 4.0 Winforms Code, I wasn't able to find the spot where the "beep" is being generated.

This leads me to believe it's beyond the control of .NET and short of blocking any key input that would cause the beep I don't think you can suppress it. Even doing this may not be sufficient because any handler you write to stop this may actually end up running after the code causing the beep.

(Left In incase someone hits this looking for that answer)

Also, this feels like you're attacking the wrong problem. My best guess is you've got some operation that's causing your app to beep a lot. Instead of suppressing the beep, why not determine what's causing the beep and eliminate the problem at the root?

Edit:

Ok, I've looked at the code for background color changing. There's really no reason changing this property should cause a system beep. The ONLY thing s I can even imagine are:

  1. You've got a handler somewhere attached to .BackColorChanged and it's causing a beep.
  2. Maybe just maybe your debug environment is not breaking on an exception that might be happening.

      if (!value.Equals((object) System.Drawing.Color.Empty) && !this.GetStyle(ControlStyles.SupportsTransparentBackColor) && (int) value.A < (int) byte.MaxValue)
         throw new ArgumentException(System.Windows.Forms.SR.GetString("TransparentBackColorNotAllowed"));
    

    This is the first code block in the setter of .BackColor on a control. Basically if the form style (theme) you're using doesn't support transparency and the color you provide has anything other than 255 in the alpha channel it'll throw an exception. It's possible your error handling / debug environment is setup in a way that that exception isn't being thrown, but swallowed and the system beep might be an indicator.

There's really too many variables here to give you a definitive answer, but I would highly suggest your start by looking there. There's really no reason a background color should cause a system beep. I can pretty much guarantee you this is actually something else.

This is a symptom of something else, and simply suppressing the beep could actually hide an underlying problem that may be causing other errors elsewhere.

It's generally best practice to not hide errors / exceptions unless you have a well defined course of action for something specific. This is why blind try/catches are discouraged as you'll take it for granted and when another error falls into that trap, you wont get the neccesary debug information to find/fix it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top