1

Summary of issue

I have a Form that is listening for the keyboard shortcut Ctrl+H using a KeyDown() method.

When the shortcut is pressed, the form opens an 'about' form:

if (e.Control && e.KeyCode == Keys.H)
{
    About about = new About();
    about.ShowDialog();
}

Whenever I press Ctrl+H, it will effectively press the backspace button as well. If I have text selected in a textbox, it will delete the selection. If I am clicked into a textbox, it deletes the last character.

Creating a minimum reproducible sample

  1. Create a new Windows Forms application using Visual Studio 2022.

  2. Add a TextBox to Form1, and make it multiline.

  3. Create a second Form called Form2. You don't need anything in that, just the form.

  4. Add a KeyDown event to Form1.

  5. In the Form1 constructor, add the following line:

KeyPreview = true;
  1. In Form1_KeyDown(), add the following code:
if (e.Control && e.KeyCode == Keys.H) {
   Form2 other = new Form2();
   other.ShowDialog();
}
  1. Run the code, type something into the textbox, then type Ctrl+H. You will see the second form pop up and a character disappear from the TextBox. Close the second window, and select all of the text in the TextBox. Type Ctrl+H again. The second form will pop up again, and all of the text will disappear from the TextBox.

Other information

I'm using Microsoft Visual Studio Community 2022 (64-bit) - Current Version 17.1.5 with Dotnet 6.0 (LTS).

I've looked through all of my code and done a fair amount of Googling. I followed the steps outlined above, and the same problem occurs, so I've isolated the problem to 2 lines:

Form2 other = new Form2();
other.ShowDialog();

The reason I add KeyPreview = true; is so that the keyboard shortcuts still work if the user is clicked into the TextBox.

There are no error messages of any sort, just the undesired behavior of the backspace button being pressed when creating a new form.

I have found nothing on the web regarding this problem. If nobody can come up with a solution, I will report it to Microsoft as a bug.

Jimi
  • 29,621
  • 8
  • 43
  • 61
REMCodes
  • 135
  • 9

2 Answers2

2

The solution is to make sure that the Form has KeyPreview set to true and add SupressKeyPress = true to your code.

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.H)
    {
        e.SuppressKeyPress = true;

        // show dialog
    }
}
Petrusion
  • 940
  • 4
  • 11
1

I just found this post that explains the solution.

How to disable a textbox keyboard shorcuts in c#?

For others who have this problem, here is the explanation.

Control+H is the ASCII code for backspace. To overcome the problem, set the textbox to readonly until the form is opened, to override the shortcut.

textBox1.ReadOnly = true;
Form2 other = new Form2();
other.ShowDialog();
textBox1.ReadOnly = false;

Hope this helps somebody!

~REMCodes

REMCodes
  • 135
  • 9
  • This is a temporary workaround rather than an actual solution. What if there are more textboxes added in the future? Or other Controls with text? You can't expect the programmer to keep adding and removing `.ReadOnly` for every Control that might be broken with this. And what if some other code wanted to make the textbox readonly for some reason? Then ctrl + H becomes a shortcut to make it writable again. – Petrusion Jul 02 '22 at 04:08
  • 1
    To process shortcuts, you should override `ProcessCmdKey` rather than setting `KeyPreview = true`. You can write `if (keyData.HasFlag(Keys.Control | Keys.H) ) { using (var f2 = new Form2()) { f2.ShowDialog(); return true; } } return base.ProcessCmdKey(ref msg, keyData);` -- This allows to process any key press before the message is delivered to the target Control. Retuning `true`, the message is suppressed, hence the target Control won't receive it. -- When you show a Form as modal Dialog, you have to declare it with a `using` statement. – Jimi Jul 02 '22 at 06:30
  • @Petrusion that is exactly why I did not mark this answer as accepted. I don't want people to think this is the best or correct way to do it. – REMCodes Jul 06 '22 at 18:00
  • @Jimi I think that your comment deserves its own answer. – REMCodes Jul 06 '22 at 18:01