Detect Key in KeyUp event - c#

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.

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.

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

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

Related

Forms, basic calculator key triggering problem

private void UserInputText_KeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode == Keys.D4 && e.Modifiers == Keys.Shift) || (e.KeyCode == Keys.Add))
{
if (String.IsNullOrEmpty(UserInputText.Text))
{
MessageBox.Show("Bir sayı giriniz.");
UserInputText.Clear();
return;
}
if (double.TryParse(UserInputText.Text, out sayı1))
{
CalculationResultText.Text = sayı1 + " + ";
islem = "+";
UserInputText.Clear();
}
else
{
MessageBox.Show("Sadece sayı değeri girebilirsiniz.");
UserInputText.Clear();
}
}
}
I am coding a basic forms calculator. I am trying to trigger addition function and clear the textbox when textbox is focused and user presses "+" key. "if (String.IsNullOrEmpty(UserInputText.Text)) and else conditions work well. But if no Message boxes shows up as in the
if (double.TryParse(UserInputText.Text, out sayı1)) condition, the "+" character remains in the textbox as in the image. Thanks for help.
If I understand correctly, you want to first check the character that was typed in and if it's incorrect then you want to prevent this character from appearing?
If so, then you need to set e.Handled = true property when you want to prevent it.
This call tells the GUI element (your TextBox) that "I did all the checks for this event (i.e. KeyDown event), and I don't want you to contribute in handling of this event (i.e. normally the TextBox would try to add this character to its Text property, but you prevent it)".
Check out documentation on KeyEventArgs.Handled.
KeyPress event enables you to prevent any further changes in the TextBox.
You can do that thanks to Handled property of KeyPressEventArgs
private void UserInputText_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '+')
{
UserInputText.Clear();
e.Handled = true;
}
}

Ignore KeyDown if the text of a RichTextBox won't change

I need to determine whether a key, when it is pressed, will change the control's text or not; I need to ignore key presses like Ctrl+Z or Esc, but I need to know which key was pressed if the text changed.
Is there any way to know that in the KeyDown event? Currently, I'm using a flag, set on KeyDown and checked on TextChanged, but I was wondering if there is a better way?
You're looking for Char.IsControl
private Keys lastKey = Keys.None;
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
lastKey = e.KeyData;
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (Char.IsControl(e.KeyChar))
{
e.Handled = true;//prevent this key press
Keys pressedKey = this.lastKey;
//Do your stuff with pressedKey here
}
}
You could catch the KeyPress event on the text box and if it is a valid key you would set e.handled = false and if it was a bad key you would set e.handled = true.
example from: here
private void keypressed(Object o, KeyPressEventArgs e)
{
// The keypressed method uses the KeyChar property to check
// whether the ENTER key is pressed.
// If the ENTER key is pressed, the Handled property is set to true,
// to indicate the event is handled.
if (e.KeyChar == (char)Keys.Return)
{
e.Handled = true;
}
}
There are some keys which produce a Control char but they also change the text, for example BackSpace. They have another difficulty: if the textbox is empty, pressing them (for example BackSpace) doesn't change the text; so it breaks the previous rule. So Control characters are not naive to deal with and build a rule upon.
Moreover, consider Ctrl + C or Shift + Insert or similar cases. The 'C' key is somehow seductive; it is like pressing 'C' changes the text but if it was pressed with 'Ctrl', it actually didn't change the text. We should check the Modifiers.
Perhaps you can find other difficulties to deal with and I think the flag approach is good enough.

Disable MaskedTextBox sound

I use a MaskedTextBox control to facilitate the entry of dates in my project. I have mtb.BeepOnError set to false. However, it makes a generic beep whenever the 'Enter' key or 'Esc' key is pressed, and this is undesirable for my application.
This seems to be the default behaviour for the MTB, so is there any way to change that?
You can try something like this:
void mtb_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.Enter | e.KeyCode == Keys.Escape) {
e.SuppressKeyPress = true;
}
}

Restrict numbers and letters in textbox - C#

I want to restrict what numbers and letters can be entered into a textbox. Let's say I only want to allow numbers 0-5 and letters a-d (both lower and uppercase).
I already tried using a masked text box but it only let me specify numbers only, letters only (both without restriction) or numbers and letters together but in a particular order.
Best scenario would be: user tries to enter number 6 and nothing gets entered into the textbox, same for letters outside the range a-f.
I think the best event to use would be the Keypress event, but I am at a loss as to how I can achieve the restriction thing.
Use the KeyPress Event for your textbox.
protected void myTextBox_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs)
{
e.Handled = !IsValidCharacter(e.KeyChar);
}
private bool IsValidCharacter(char c)
{
bool isValid = true;
// put your logic here to define which characters are valid
return isValid;
}
// Boolean flag used to determine when a character other than a number is entered.
private bool nonNumberEntered = false;
// Handle the KeyDown event to determine the type of character entered into the control.
private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
// Initialize the flag to false.
nonNumberEntered = false;
// Determine whether the keystroke is a number from the top of the keyboard.
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
{
// Determine whether the keystroke is a number from the keypad.
if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)
{
// Determine whether the keystroke is a backspace.
if(e.KeyCode != Keys.Back)
{
// A non-numerical keystroke was pressed.
// Set the flag to true and evaluate in KeyPress event.
nonNumberEntered = true;
}
}
}
//If shift key was pressed, it's not a number.
if (Control.ModifierKeys == Keys.Shift) {
nonNumberEntered = true;
}
}
// This event occurs after the KeyDown event and can be used to prevent
// characters from entering the control.
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
// Check for the flag being set in the KeyDown event.
if (nonNumberEntered == true)
{
// Stop the character from being entered into the control since it is non-numerical.
e.Handled = true;
}
}
Override the PreviewKeyDownEvent like this:
private void textBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.A || e.KeyCode == Keys.B || ...)
e.IsInputKey = true;
else
e.IsInputKey = false;
}
This will tell the textBox which keys it will consider as a user input or not.
Use the KeyDown event and if the e.Key is not in your allowable set, then just e.Handled = true.
An alternative would be accept all input, validate it and then provide useful feedback to the user, for example an error label asking them to enter data within a certain range. I prefer this method as the user knows something went wrong and can fix it. It is used throughout the web on web forms and would be not at all surprising for a user of your app. Pressing a key and getting no response at all might be confusing!
http://en.wikipedia.org/wiki/Principle_of_least_astonishment
The Keypress event is probably your best bet. Do a check there if the entered char is not the char you want, set e.SuppressKey to true to make sure the KeyPress event is not fired, and the char is not added to the textbox.
If you are using ASP.NET Web Forms a regular expression validation would be the easiest. In MVC, a jQuery library such as MaskedEdit would be a good place to start. The answers above document the Windows forms approach well.

how to make a multiline textbox not accept Enter and Backspace

I have a multiline textbox which shouldn't accept alphabets, numbers, newline(enter key) and backspace. In short, the textbox.Text shouldn't be editable. But I do want the textbox to accept two shortcut keys - control and control+R. One way I can make the textbox un-editable is by making it read-only. But then the textbox wont accept any keystroke at all. In short, my shortcuts ( control and control+R) wont work( Control + R) with read-only method.
Can anyone help in this regard. That's all I have to do.
One thing I could do here is not to make the textbox read-only and then restrict the characters(alphabets and digits) that could be inputted in the textbox. With this code:
private void txtResult_KeyPress(object sender, KeyPressEventArgs e)
{
// only modifier keys, escape, enter, backspace etc is accepted now
e.Handled = !char.IsControl(e.KeyChar);
}
private void txtResult_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control == true)
{
if (e.KeyCode == Keys.R)
{
// do something
}
else
{
//do something
}
}
if (e.KeyCode == Keys.Escape)
{
//do something
}
}
With this technique I can get the shortcuts(control and control+R) working. But the trouble with this method is that Enter and Backspace keys work as well making it possible to edit the text of textbox. How can I specifically restrict Enter and Backspace key being registered from the textbox, but let Control and Escape??
did you try SuppressKeyPress = true ?
private void textBox2_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control == true)
{
if (e.KeyCode == Keys.R)
{
// do something
}
else
{
//do something
}
}
else
e.SuppressKeyPress = true;
}
Since you are handling the keys in the KeyDown event handler, why not have your KeyPress handler return that all keystrokes are handled?
So just set e.Handled = true no matter what. I believe the backspace and enter would be interpreted as control characters, also.
The Enter and Backspace keys won't work if the textbox is set to ReadOnly, as you suggested early on in the question that you had done. Make sure the property is still set to true. You can either set it in the Properties window, or through code like so:
myTextBox.ReadOnly = true;
Then, you need to handle the KeyDown event for the textbox control, and watch for the specific keys that you're interested in. Something like this:
private void myTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control)
{
if (e.KeyCode == Keys.R)
{
MessageBox.Show("Pressed Ctrl+R");
}
else
{
MessageBox.Show("Pressed Ctrl");
}
}
else if (e.KeyCode == Keys.Escape)
{
MessageBox.Show("Pressed Esc");
}
}
This works exactly as expected, as long as the textbox is set to read-only. No other keys are recognized, and the user cannot change or modify any of the text in the textbox. You don't need to suppress the keypresses, as the control is already doing that when you set it to read-only. You also don't need to handle both the KeyDown and KeyPress events. KeyPress won't work for you anyway, as it doesn't let you handle control characters.

Categories

Resources