0

How to prohibit the introduction of letters in textBox? That is, this construction works incorrectly

public void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    try
    {
        char s = Convert.ToChar(textBox1.Text);
        if ((s <= '0') || (s >= '9'))
            MessageBox.Show("You have entered a symbol! Please enter a number");
    }
    catch (System.FormatException)
    {
        MessageBox.Show("You have entered a symbol! Please enter a number");
    }
}
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • 2
    The user can still paste text into this control. Consider a MaskedTextBox control instead. – LarsTech Mar 29 '16 at 14:56
  • Depending on what type of numeric data you're capturing, you may also want to consider a `NumericUpDown` control instead of a `Textbox`. – Steve Mar 29 '16 at 15:02
  • Possible duplicate of [How do I make a textbox that only accepts numbers?](http://stackoverflow.com/questions/463299/how-do-i-make-a-textbox-that-only-accepts-numbers) – Alex K. Mar 29 '16 at 15:58

3 Answers3

2

You need to either check the key being entered in the KeyDown event (e.Key property) as the key value is added to the Text field after the event or use the TextChanged event - this would catch cut & paste operations as well.

public void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{        
    if (!ValidNumericString(textBox1.Text))
    {
        MessageBox.Show("You have entered invalid characters! Please enter a number");
        Dispatcher.BeginInvoke(new Action(() => textBox1.Undo()));
        e.Handled = true;
    }
}

public bool ValidNumericString(string IPString)
{
    return IPString.All(char.IsDigit);
    // OR make this check for thousands & decimals if required
}
PaulF
  • 6,673
  • 2
  • 18
  • 29
  • 1
    Wouldn't that break on decimals and thousand separators? – 0xFF Mar 29 '16 at 15:35
  • 1
    If that is required, then I would create a specific method to check the validity of the string rather than check for all digits. – PaulF Mar 29 '16 at 15:38
  • 1
    Updated to use a method to check the string & show how to invoke the Undo method of the TextBox - it cannot be called directly as the undo information is being created when the TextChanged event fires. – PaulF Mar 29 '16 at 16:11
1

You can use the OnKeyPress event which allows you to cancel the key event manually if you want to.

void textBox1_OnKeyPress(KeyPressEventArgs e)
{
    e.Handled = true;   // this won't send the key event to the textbox
}

If you want to accept only numbers and related chars (negative sign, decimal separators, ...), you can test the entered char :

void textBox1_OnKeyPress(KeyPressEventArgs e)
{
    NumberFormatInfo numberFormatInfo = CultureInfo.CurrentCulture.NumberFormat;
    string decimalSeparator = numberFormatInfo.NumberDecimalSeparator;
    string groupSeparator = numberFormatInfo.NumberGroupSeparator;
    string negativeSign = numberFormatInfo.NegativeSign;

    string keyInput = e.KeyChar.ToString();

    e.Handled = !(Char.IsDigit(e.KeyChar) || keyInput.Equals(negativeSign) || keyInput.Equals(decimalSeparator) || keyInput.Equals(groupSeparator));
}

This is untested code because I'm at work, but you get the idea.

G.Vernier
  • 369
  • 2
  • 14
  • 2
    I don't think this would correctly work for Paste actions (Ctrl-V) - though I may be wrong. – PaulF Mar 29 '16 at 16:24
  • 1
    Just tried it on a project I implemented that method in; ctrl+v shortcut is ignored, but pasting from context menu seems to allow it... – G.Vernier Mar 29 '16 at 16:34
0
    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
        if (Control.ModifierKeys == Keys.Control) return; // Check if ctrl is pressed
        var key = (char) e.KeyValue; // ASCII to char
        if (char.IsDigit(key) || char.IsControl(key) || char.IsWhiteSpace(key)) return; // Check if "key" is a number
        MessageBox.Show("You have entered a symbol! Please enter a number"); 
        textBox1.Text = textBox1.Text.Substring(0, textBox1.Text.Length - 1); // Remove last element
        textBox1.SelectionStart = textBox1.Text.Length; // Return to initial position
    }
NoName
  • 95
  • 1
  • 11
  • This code has at least several problems - firstly with the KeyDown event the character has not been added to the textbox string at that point - if the invalid character is the first entered then you will get an exception as the substring length will be -1, if the invalid character is not the first then you will be removing whatever the last character is, not the invalid character. Also you make the assumption that the insertion point is at the end of the string - the insertion point could be anywhere. – PaulF Mar 30 '16 at 08:20