Problems inserting "|" instead of " " when space key is pressed - c#

I have a TextBox control. After pressing space, I want, instead of whitespace, to put "|". This is my code:
void TextBox1KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Space)
{
textBox1.AppendText("|");
}
}
Problem is it doesn't write only "|", but "| ": After the pipe char, it puts a space and the cursor moves after that space. I tried to use this method:
textBox1.Text = textBox1.Text.Substring(0, (textBox1.TextLength - 1));
but it doesn't work because it deletes "|" instead of the space.
And another question is: I want to disable inserting " " when Space is pressed when textbox is empty. When u want to press space while textbox is empty, nothing happens, textbox will stay empty and cursor stay at the begining of textbox
i try this
void TextBox1KeyDown(object sender, KeyEventArgs e)
{
if (textBox1.Text.Length==0 && e.KeyCode == Keys.Space) {
textBox1.Text=string.Empty;
}
}
It doesnt work cause same reason like my previous question. That event is handled after " " is already added so textbox is not empty
PS: sorry for my english and thanks to whoever edit my post and fix my grammatical and spellig errors

Instead of KeyPress handle your requirement in the KeyDown event
void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Space && e.Modifiers == Keys.None)
{
e.SuppressKeyPress = true;
textBox1.AppendText("|");
}
}
As noted below from DrewMcGowen, this will add always the pipe at the end of the textbox text. If you move the cursor somewhere inside the current text the behavior of this approach is confusing and probably incorrect.
This code instead tries to place the pipe exactly where the cursor is
void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Space && e.Modifiers == Keys.None)
{
e.SuppressKeyPress = true;
int pos = textBox1.SelectionStart;
textBox1.Text = textBox1.Text.Substring(0, pos) + "|" + textBox1.Text.Substring(pos);
textBox1.SelectionStart = pos + 1;
}
}
Notice also that a check on the value of the Modifiers property of the KeyEventArgs parameter is mandatory. For example ALT+SPACE should activate the System Menu and not change your textbox in any way (see comment below from Mr HansPassant). Checking for Keys.None will avoid this logic also for CTRL and SHIFT modifiers, if you want these modifiers to be accounted for you need to change that check.

The OnKeyPress event is fired before the space is added.
The workflow is thus:
You press down [Space];
The event is fired adding | to the content; and
The space event itself is handled adding a space to the content.
You need to use KeyRelease or KeyUp...

Documentation says:
Use the KeyChar property to sample keystrokes at run time and to modify keystrokes under special run-time circumstances. For example, you can use KeyChar to disable non-numeric keypresses when the user enters a ZIP code, change all alphabetical keypresses to uppercase in a data entry field, or monitor the keyboard or other key input device for specific key combinations.
So all you need is
if (e.KeyChar == ' ')
{
e.KeyChar = '|';
}

You forgot e.Handled = true; to suppress the space.
Monkeying with the user input is rather unwise. It is very disorienting and plain just doesn't work in some cases. Obvious failure modes are the user typing Ctrl+V or using right-click + Paste to insert text. Do this correctly with the Validating event:
private void textBox1_Validating(object sender, CancelEventArgs e) {
textBox1.Text = textBox1.Text.Replace(' ', '|');
}
With high odds that you want to further improve this code by checking for two || next to each other or a leading or trailing |. You can set e.Cancel = true when you're unhappy, use ErrorProvider to give the user hints.

Related

Suppress the display of the input into the TextBox

I have a winforms program containing a RichTextBox.
The user inputs the text into the RichTextBox.
I wish to receive the input through keyboard events and not through textBox1.Text property, validate the string and only display it in the RichTextBox later.
How can I prevent the RichTextBox from displaying the input text by the user, even though the user inputs the text into the RichTextBox?
The RichTextBox is selected and has focus.
I am sorry. I just wanted to simplify the issue and therefore I neglected to mention that it is not a TextBox but a RichTextBox. It turns out that it matters, as the proposed solution is based on the PassowrdChar property, which is not natively supported by RichTextBox. I do not wish to create an inherited class for a property which is not even being used as such, only to suppress displaying the user input at input time.
You can actually use the KeyDown event. By doing that, you have an ability to validate the user input.
Tutorial
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
//
// Detect the KeyEventArg's key enumerated constant.
//
if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("You pressed enter! Good job!");
}
else if (e.KeyCode == Keys.Escape)
{
MessageBox.Show("You pressed escape! What's wrong?");
}
}
With that said, you have to store user input in string variable, validate it through the event and only then set variable value in textbox.
You can use this:
private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
char c = e.KeyChar;
// ..
// handle the character as needed
// ..
e.Handled = true; // suppress the RTB from receiving it
}
Note that you may or may not want to treat mouse events like right mouseclicks to control inserting via the mouse..

How to make TextBox to receive only number key values using KeyDown Event in C#?

This code in my form updates the textBox1.Text twice whenever number keys are pressed.
private void textBox1_KeyDown( object sender, KeyEventArgs e ) {
//MessageBox.Show();
if( char.IsNumber((char)e.KeyCode) ) {
textBox1.Text += (char)e.KeyCode;
}
}
Explain why if you can?
Modify the code or provide me a better solution for this.
Input ( in textbox1 ):
54321
Output:
1234554321
When you press a key, a character is already appended to your TextBox. Then you run the following code and, if the key represents a number, you append it again:
if (char.IsNumber((char)e.KeyCode)) {
textBox1.Text += (char)e.KeyCode;
}
If you want to suppress any key that's not a number, you could use this instead:
e.SuppressKeyPress = !char.IsNumber((char)e.KeyCode);
From the syntax I assume you are using WinForms for the following answer.
The key pressed event is not suppressed, so it still works like a normal key pressed event and adds the character to the text of the box. Additionally you add the character to the text yourself once again.
Try to suppress the key pressed event in case a key is pressed, you do not want to allow.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (!char.IsNumber((char)e.KeyCode))
{
e.SuppressKeyPress = true;
}
}
You can try like this:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = !(e.KeyValue >= 48 && e.KeyValue <= 57);
}
Check New keyboard APIs: KeyEventArgs.SuppressKeyPress
The problem is that "Handled" doesn't take care of pending WM_CHAR
messages already built up in the message queue - so setting Handled =
true does not prevent a KeyPress from occurring.
In order not to break anyone who has currently got e.Handled =
true, we needed to add a new property called SuppressKeyChar. If we
went the other way, if "handling" a keydown suddenly started to
actually work, we might break folks who accidentally had this set to
true.
Try this code to accept numbers only
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar))
e.Handled = true;
}

NumericUpDown error MessageBox

I would like to ask what code should I insert to to my "numGPA" to inform the user that they have exceeded the "maximum".
Right now if the try to "submit" a value above the maximum, my visual studio will only play a "ding" sound.
Instead of that I would like to have a message box that says something like "Only a value from 0 to 4 is allowed"
I found this code on Google and despite me changing the numericUpDown1 to numGPA it does not work.
if (numGPA.Value >= 4 || numGPA.Value <= 0)
{
MessageBox.Show("Error. Number must be between 0 and 4");
numGPA.Value = 1;
numGPA.ReadOnly = true;
}
Do take a look at this video to get a clear picture of what I am saying
https://www.youtube.com/watch?v=XVv-it6x044&feature=youtu.be
Instead of the "ding" sound effect played #0.06, I would like a MessageBox.
You can do that with the TextChange event. You can (and should) also set the minimum and maximum properties to limit the input with the arrows.
Private Sub NumericUpDown1_Changed(sender As Object, e As EventArgs) Handles NumericUpDown1.TextChanged
If IsNumeric(NumericUpDown1.Text) AndAlso _
CInt(NumericUpDown1.Text) > NumericUpDown1.Maximum Then MsgBox("Oops! Too big.")
End Sub
The best way is to let the user edit and only check when he has finished. This will trigger the ValueChanged event.
Here we can get at the entered value by grabbing the internal TextBox control.
I suggest using a helper function, maybe like this:
void nudCheck(NumericUpDown nud)
{
TextBox tb = (TextBox) nud.Controls[1];
if (Convert.ToInt32(tb.Text) > nud.Maximum)
{
string msg = tb.Text + " is too large! Setting value to maximum: " + nud.Maximum;
tb.Text = "" + nud.Maximum;
nud.Value = nud.Maximum;
// do what you want with the message string!
//MessageBox.Show(msg); // not recommended!
toolTip1.Show(msg, nud); // add a ToolTip component to your form for this!
}
}
Call it here:
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
nudCheck(numericUpDown1);
}
We also want to suppress the error sound for the case when the user presses Enter, best in the KeyDown event..
private void numericUpDown1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
nudCheck(numericUpDown1);
e.SuppressKeyPress = true;
}
}
Note that bringing up an actual MessageBox will bring back the bell sound and force the user to get rid of it. So I have used a ToolTip, but a Label would also work, if you have the space..
Obviously you may want to add similar code to check input lower than the Minimum..

How to restrict user to TextBox if value entered is incorrect

In my program I have a TextBox who's value must be set in a specific integer range. If it is not within this range, it should warn the user and then highlight the incorrect text inside of the TextBox for re-editing (implying that the user must enter a value that is in the correct range before they are allowed to leave the TextBox). How would I change my code so that it performs these operations?
This is what I have so far. I am using a TextChanged event. This code warns the user about the restriction breach and refocuses (I would like to highlight the value instead) on the TextBox, but does not prevent the user from clicking out of it afterward:
int maxRevSpeed;
//Max Rev Speed -- Text Changed
private void maxRevSpeed_textChanged(object sender, RoutedEventArgs e)
{
if (maxRevSpeed_textBox.Text == "" || maxRevSpeed_textBox.Text == " ")
maxRevSpeed = 0;
else
{
maxRevSpeed = Convert.ToInt32(maxRevSpeed_textBox.Text);
if (maxRevSpeed <= 0 || maxRevSpeed > 45)
{
MessageBox.Show("Reverse Sensor speed must be between 0 and 45 FPM", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
}
maxRevSpeed_textBox.Focus();
}
}
Please note that this question is a revisit of a former question of mine. I am aware that it may be "frowned upon" to take this approach to a TextBox, but regardless I would still like to figure out how to implement such a thing. Thank you.
Update 1:
After looking at everyone's suggestions I have updated my code:
//Max Rev Speed -- Text Changed
private void maxRevSpeed_textChanged(object sender, RoutedEventArgs e)
{
if (maxRevSpeed_textBox.Text == "" || maxRevSpeed_textBox.Text == " ") //Is Empty or contains spaces
maxRevSpeed = 0;
else if (!Regex.IsMatch(maxRevSpeed_textBox.Text, #"^[\p{N}]+$")) //Contains characters
maxRevSpeed = 0;
else
maxRevSpeed = Convert.ToInt32(maxRevSpeed_textBox.Text);
}
//Max Rev Speed -- Lost Focus
private void maxRevSpeed_LostFocus(object sender, RoutedEventArgs e)
{
if (maxRevSpeed <= 0 || maxRevSpeed > 45)
{
MessageBox.Show("Reverse Sensor speed must be between 0 and 45 FPM", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
//Supposed to highlight incorrect text -- DOES NOT WORK
maxRevSpeed_textBox.SelectionStart = 0;
maxRevSpeed_textBox.SelectionLength = maxRevSpeed_textBox.Text.Length;
}
}
The integer representing the text in the textBox is now dealt with in the textChanged event. The LostFocus event handles the warning and the re-selection of the incorrect text value. However, the highlight text method works when it is in the textChanged event, but not in it's current location. Why is that, and how can I fix it?
If you just want to stop focus from leaving a TextBox, all you need to do is to set the Handled property of the KeyboardFocusChangedEventArgs object to true in a PreviewLostKeyboardFocus handler when your invalid condition is true:
private void PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
e.Handled = IsInvalidValue;
}
This of course assumes that you have a property named IsInvalidValue that you set to true when the entered data is invalid and false otherwise.
You can prevent the user from entering the text or out of range by using PreviewTextInput handler of textbox, call it like this.
private void textBox1_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
if (!char.IsDigit(e.Text, e.Text.Length - 1))
{
e.Handled = true;
}
}
The code above is for entering numbers only, you can change it according to your requirements, hope it helps :)
Hi I suppose you are using C#, here you can find a relevant post: C# auto highlight text in a textbox control
As they stated the following code should select the text inside texbox
In Windows Forms and WPF:
maxRevSpeed_textBox.SelectionStart = 0;
maxRevSpeed_textBox.SelectionLength = textbox.Text.Length;

How to make Textbox only accept alphabetic characters

I have a windows forms app with a maskedtextbox control that I want to only accept alphabetic values in.
Ideally, this would behave such that pressing any other keys than alphabetic keys would either produce no result or immediately provide the user with feedback about the invalid character.
This question has probably been asked and answered a million times on every conceivable programming forum. Every answer provided has the distinction of being unique to the stated requirements.
Since you are using a MaskedTextBox, you have additional validation features available to you and do not really need to handle keypresses. You can simply set the Mask property to something like "L" (character required) or "?" (optional characters). In order to show feedback to the user that the input is not acceptable, you can use the BeepOnError property or add a Tooltip to show the error message. This feedback mechanism should be implemented in the MaskedInputRejected event handler.
The MaskedTextBox control offers a ValidatingType property to check input that passes the requirements of the Mask, but may not be the correct datatype. The TypeValidationCompleted event is raised after this type validation and you can handle it to determine results.
If you still need to handle keypress events, then read on...!
The method I would recommend in your case is that instead of handling the KeyDown event (you ostensibly do not need advanced key handling capability) or using a Regex to match input (frankly, overkill), I would simply use the built-in properties of the Char structure.
private void maskedTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
Char pressedKey = e.KeyChar;
if (Char.IsLetter(pressedKey) || Char.IsSeparator(pressedKey) || Char.IsPunctuation(pressedKey))
{
// Allow input.
e.Handled = false
}
else
// Stop the character from being entered into the control since not a letter, nor punctuation, nor a space.
e.Handled = true;
}
}
Note that this snippet allows you to handle punctutation and separator keys as well.
From MSDN (This code shows how to handle the KeyDown event to check for the character that is entered. In this example it is checking for only numerical input. You could modify it so that it would work for alphabetical input instead of numerical):
// 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;
}
}
This code will distinguish alphabetic character key presses from non alphabetic ones:
private void maskedTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (Regex.IsMatch(e.KeyChar.ToString(), #"\p{L}"))
{
// this is a letter
}
else
{
// this is NOT a letter
}
}
Update: note that the above regex pattern will match ONLY alphabetic characters, so it will not allow spaces, commas, dots and so on. In order to allow more kinds of characters, you will need to add those to the pattern:
// allow alphabetic characters, dots, commas, semicolon, colon
// and whitespace characters
if (Regex.IsMatch(e.KeyChar.ToString(), #"[\p{L}\.,;:\s]"))
// This is to allow only numbers.
// This Event Trigger, When key press event occures ,and it only allows the Number and Controls.,
private void txtEmpExp_KeyPress(object sender, KeyPressEventArgs e)
{
if(Char.IsControl(e.KeyChar)!=true&&Char.IsNumber(e.KeyChar)==false)
{
e.Handled = true;
}
}
//At key press event it will allows only the Characters and Controls.
private void txtEmpLocation_KeyPress(object sender, KeyPressEventArgs e)
{
if (Char.IsControl(e.KeyChar) != true && Char.IsNumber(e.KeyChar) == true)
{
e.Handled = true;
}
}
//Add a text box select it & goto Events & In the event list double click on "keypress" event.
if (!char.IsLetter(e.KeyChar))
{
MessageBox.Show("Enter only characters");
}
}
This works for me :)
private void txt_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !((e.KeyChar != 'ñ' && e.KeyChar != 'Ñ') && char.IsLetter(e.KeyChar));
}
Try this code
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !(char.IsLetter(e.KeyChar) || e.KeyChar == (char)Keys.Back || e.KeyChar == (char)Keys.Space);
}

Categories