4

I have a textbox on a form where I'm trying to detect the keys the user types in. The TextBox is multilined with wordwrap on. I don't want the user the press the enter key (as I want all text entered on ONE line, wrapped) so I used the following code:

private void txtPlain_KeyPress(object sender, KeyPressEventArgs e) {
    if (e.KeyChar == (char)13) {
        MessageBox.Show("Enter keys are not allowed");
        e.KeyChar = (char)0;
    }
}

This worked fine in my tests, but when I tested for CTRL+ENTER it didn't work as I'm not sure how to detect for the control key. From my googling I found that I need to use the KeyUp/Down events so I now have the following Code:

private void txtPlain_KeyUp(object sender, KeyEventArgs e) {
    //if (e.KeyData == (Keys.Control | Keys.Enter)) {

    if (e.KeyCode == Keys.Enter || (e.KeyCode == Keys.Enter && e.Control)) {            
        MessageBox.Show("Enter keys are not allowed:");
        //e.KeyValue = Keys.None;
    }
}

The first commented out line didn't work for some reason so if anyone could explain why this would be useful.

The problem with the KeyUp/Down event is that I don't know how to REMOVE the enter key from the text - unlike the KeyPress event when I can set the KeyChar to zero. The event captures both the Enter and Ctrl+Enter keys, but the cursor still goes to the next line in the TextBox.

Thanks for any help on this.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Harag
  • 1,532
  • 4
  • 19
  • 31
  • If this is a WinForm, then performing keypress detection like this is fine...but if this is a WebForm, then sending keypress event back to the server is a bad idea (because it's creates a chatty). If this IS a WebForm try using something like jQuery to detect keypress events. – Prisoner ZERO May 11 '11 at 11:32
  • @Prisoner: Hmm, the `Keys` enumeration is defined in the `System.Windows.Forms` namespace. It's quite unlikely that this is a Web Forms application. – Cody Gray - on strike May 11 '11 at 11:33
  • @Cody Thanks...I didn't even think to look-up the namespace. – Prisoner ZERO May 11 '11 at 17:53

3 Answers3

5

Hmm, there's no reason to disallow the Enter key by handling the KeyDown or KeyUp events. You can simply set the AcceptsReturn property of the textbox control to False. This will prevent a multiline textbox from responding to a press of the Enter key.

Of course, this doesn't solve the problem of Ctrl+Enter. In fact, that's the expected way to create a new line when the AcceptsReturn property is set to False. To solve that, you will need to handle one of the keyboard events and prevent the control from receiving this input.

KeyDown is a good place to start. What you want to do is filter out any keyboard events that include the Keys.Enter flag. That will catch them no matter which other modifier key they might be combined with. Then, once you've found an Enter keypress, you want to set the e.Handled property to True in order to prevent it from being passed on to the control.

But unfortunately, we're not quite done yet. The textbox control tries to handle certain keys internally, and you're not going to be able to override that in a key event handler method. You also need to tell the control not to interpret that particular key as an input key. There are two primary ways of doing this. The first (and recommended way) is to inherit from the base TextBox class to create your own custom control, and then override the protected IsInputKey method. The second (somewhat simpler) way is just to handle the PreviewKeyDown event, and set the IsInputKey property to False.

Sample code:

private void txtPlain_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    // Check if the KeyCode value has the Keys.Enter flag set
    if ((e.KeyCode & Keys.Enter) == Keys.Enter)
    {
        // Set the IsInputKey property to False
        e.IsInputKey = false;
    }
}

private void txtPlain_KeyDown(object sender, KeyEventArgs e)
{
    // Check if the KeyCode value has the Keys.Enter flag set
    if ((e.KeyCode & Keys.Enter) == Keys.Enter)
    {            
        // Show the user a message
        MessageBox.Show("Enter keys are not allowed in this textbox.");

        // Prevent the key event from being passed on to the control
        e.Handled = true;
    }
}

And, though I assume this is for testing purposes only, you definitely want to take that MessageBox call out of there for production code. Find another way to alert the user that their input was not allowed, such as a short beep sound and an ErrorProvider component placed next to the textbox. Showing a message box is very jarring, and not very user-friendly. See my answer here for other hints and tips.

Community
  • 1
  • 1
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • thanks for the above... couple of things 1 - I do have the "AcceptsReturn" set to false (by default), but return keys still move the cursor to the next line. - strange! - 2 - I've put in the code above in the Keydown event, the messagebox pops up, but the enter key is still added to the text box (even with ctrl). 3 - Yes the message box is for testing only so will be removed. Thanks – Harag May 11 '11 at 11:45
  • I've just seen the edited post with the PreviewKeyDown event, created a new windows app, so just have a form with one text box - set multiline to false (acceptreturns and wordwrap as defautlt). added the above code - and still nothing - the message box shows so it's capturing the Enter Key. – Harag May 11 '11 at 12:04
  • @harag: Erm, the message box is *supposed* to show if the Enter key is pressed. Am I misunderstanding what you want to accomplish? – Cody Gray - on strike May 11 '11 at 12:05
  • @Cody Gray - yes it's suppose to show - but only while I was testing it. now the condition works the messagebox will be removed. - As you say an alternative way for alerting the user is better. – Harag May 11 '11 at 12:14
  • @harag: So take that line out. I'm not sure what the problem is. – Cody Gray - on strike May 11 '11 at 12:16
  • @Cody Gray - the message line has been removed, but the code above still doens't work. enter keys are still added to the text box. Gabriel edited code above seems to work though with the keypress and down events. – Harag May 11 '11 at 12:19
1
private void txtPlain_KeyUp(object sender, KeyEventArgs e) {
    //if (e.KeyData == (Keys.Control | Keys.Enter)) {

    if (e.KeyCode == Keys.Enter || (e.KeyCode == Keys.Enter && e.Control)) {            
        MessageBox.Show("Enter keys are not allowed:");
        //e.KeyValue = Keys.None;
        // mark event as handled
        e.Handled = true;
    }
} 

from msdnlink

edit:

I think that you need the key down event not the key up

EDIT2
here is some tested code and it works as you wanted:

        bool invalid=false;
        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.KeyCode & Keys.Enter) == Keys.Enter)
            {
                invalid = true;
            }
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (invalid)
            {
                e.Handled = true;
            }
            invalid = false;
        }
Gabriel
  • 1,435
  • 3
  • 17
  • 24
  • I've tried the e.Handled in both KeyUp and KeyDown, but nothing happens. Thanks for the MSDN link - but looking at that it looks like it uses both the KeyDown Event and the Keypress. which is what I might need to do in this case. – Harag May 11 '11 at 11:36
  • There's absolutely no reason you would need to handle both `KeyDown` and `KeyPress`. The MSDN sample is silly. – Cody Gray - on strike May 11 '11 at 11:39
  • @harag hope it work's for you . I've used e.Handle = true; and the event has not sent further. – Gabriel May 11 '11 at 11:40
  • @Gabriel - I've tried teh e.Handled in both the Up and Down events but this doesn't seem to be working. – Harag May 11 '11 at 11:50
  • @Cody the MSDN sample is not silly. e.Handle must be used in KeyPress not in KeyDown – Gabriel May 11 '11 at 12:05
  • @Cody I don't know why. I will ask in MSND forum maybe they can tell me – Gabriel May 11 '11 at 12:09
  • @Gabriel - Thanks for the edited code above with the two events. I've put this in my app and it DOES work - though my other sub questions in comments are still a mystery as to why they don't work - eg. AcceptReturns = false property. – Harag May 11 '11 at 12:12
  • @harag also from msdn: If the value of this property is false, the user must press CTRL+ENTER to create a new line in a multiline TextBox control. If there is no default button for the form, the ENTER key will always create a new line of text in the control, regardless of the value of this property – Gabriel May 11 '11 at 12:23
  • @Gabriel - thanks for the explanation on the AcceptReturns, much appreciated – Harag May 11 '11 at 13:24
0

The first commented out line didn't work for some reason so if anyone could explain why this would be useful.

You wanted to detect Ctrl + Enter. if (e.KeyData == (Keys.Control | Keys.Enter)) {..

Keys.Control and Key.Enter are nothing but are some values please refer . Now doing logical or will not necessarily result to key which has been pressed. Totally illogical clause.

Ok now come to your actual problem you want to detect Enter stroke and Ctrl + Enter stroke to be treated as same. Besides you want to undo the newline character thats been introduced. Try

PreviewKeyDown or Preview key up eventhandler with the following condition

if(e.KeyCode==Keys.Enter)

Let me know if this works

Amit Gupta
  • 577
  • 4
  • 14
  • Yeah, you *totally* misunderstood the question *and* the code snippet. That's not a logical OR, it's a **bitwise** OR, and it's absolutely the correct thing to do here. Even the documentation you link to says that the `Keys` enum has the `FlagsAttribute`, indicating that it allows a bitwise combination of its values. – Cody Gray - on strike May 11 '11 at 11:58