locked
Programming a textbox to only accepts numbers RRS feed

  • Question

  •  private void textBox5_TextChanged(object sender, EventArgs e)
            {
    
                int i = 0;
    
                textBox5.Text = textBox5.Text.Trim();
    
                if (Int32.TryParse(textBox5.Text, out i))
                {
    
                    temptb = textBox5.Text;
    
                }
    
                else
    
                    textBox5.Text = temptb;
    
                textBox5.SelectionStart = textBox5.Text.Length;
    
    
    
               
            }

    I have this code, and it works fine for only allowing numbers in the box, but once you input a number such as "300" it only deletes the two "00" and the 3 can not be deleted, even when I clear all lines. The only way to change the existing number in the text box is to Highlight it with the mouse and input a new digit.

    I am wondering how to enable the code to allow me to delete all digits in the the one single text box (textBox5).

    Monday, June 25, 2012 9:39 PM

Answers

  • I would use a KeyPress event:

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
          //allows backspace key
          if (e.KeyChar != '\b')
          {
            //allows just number keys
            e.Handled = !char.IsNumber(e.KeyChar);
          }
        }


    Mitja

    • Marked as answer by Lisa Zhu Tuesday, July 3, 2012 7:42 AM
    Tuesday, June 26, 2012 12:12 AM
  • Hi, 

    You can extend TextBox that allows only numerics like, 

    public class NumericalTextBox : TextBox
    	{
    		protected override void OnKeyPress(KeyPressEventArgs e)
    		{
    			if (((char.IsNumber(e.KeyChar))) || (((int)e.KeyChar) == 8) || (((int)e.KeyChar) == 46))
    			{
    				return;
    			}
    			e.Handled = true;
    		}
    	}
    Hope this helps you...


    If this post answers your question, please click "Mark As Answer". If this post is helpful please click "Mark as Helpful".

    • Marked as answer by Lisa Zhu Tuesday, July 3, 2012 7:48 AM
    Tuesday, June 26, 2012 2:01 AM
  • Hello,

    You can do something like that to handle the signs/separators properly.

    using System.Linq;
    	using System.Globalization;
    	using System.Windows.Forms;
    
    	public partial class AppMain : Form
    	{
    		private readonly NumberFormatInfo numberFormatInfo = CultureInfo.CurrentCulture.NumberFormat;
    
    		private readonly char[] signs;
    
    		public AppMain()
    		{
    			InitializeComponent();
    
    			signs = new[]
    			{
    				char.Parse(numberFormatInfo.NumberDecimalSeparator),
    				char.Parse(numberFormatInfo.NumberGroupSeparator),
    				char.Parse(numberFormatInfo.NegativeSign)
    			};
    
    			textBox1.KeyPress += TextBox1KeyPress;
    		}
    
    		private void TextBox1KeyPress(object sender, KeyPressEventArgs e)
    		{
    			bool exists = signs.Any(ch => e.KeyChar == ch);
    
    			if (exists || e.KeyChar >= 48 && e.KeyChar <= 57 || e.KeyChar == 8)
    			{
    				return;
    			}
    
    			e.Handled = true;
    		}
    	}

    P.s if you don't like/understand/whatever LINQ you can change "signs.Any(ch => e.KeyChar == ch);" to "Array.Exists(signs, ch => e.KeyChar == ch);" -- A subtle difference. :)

    Mitja Bonca's function is successful,you can try!

    I share your excitement, it happens to me too but please, the next time you post make sure you take the time and write something more constructive.


    Eyal (http://shilony.net), Regards.

    • Edited by Eyal Solnik Tuesday, June 26, 2012 4:47 AM
    • Marked as answer by Lisa Zhu Tuesday, July 3, 2012 7:49 AM
    Tuesday, June 26, 2012 4:31 AM
  • try this 

    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (!char.IsControl(e.KeyChar) 
            && !char.IsDigit(e.KeyChar) 
            && e.KeyChar != '.')
        {
            e.Handled = true;
        }
    
        // only allow one decimal point
        if (e.KeyChar == '.' 
            && (sender as TextBox).Text.IndexOf('.') > -1)
        {
            e.Handled = true;
        }
    }

    good luck

    • Marked as answer by Lisa Zhu Tuesday, July 3, 2012 7:49 AM
    Tuesday, June 26, 2012 4:44 AM
  • Then use the code I pasted in my 1st post up above, or someone elses. There is plenty of working code for you. But use KeyPress event, not TextChanged, like you did.

    It's actually important to use TextChanged, not KeyPress, for sanitizing input like this.

    When running your code do the following:

    1. Highlight the following: "Not a number!"
    2. Copy it to your clipboard.
    3. Right click on the textbox that should only be allowed to be a number.
    4. Select Paste.

    Your 'numeric only' textbox now says, "Not a number!".

    @OP, your code is quite good.  To be honest, it's better than all of the suggestions I've seen here.  If you want the user to be able to delete all of the characters you only need to add an additional "if" so that you don't even try to parse the textbox if it's empty.  See code below:

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        int i;
    
        textBox5.Text = textBox5.Text.Trim();
    
        if (!string.IsNullOrEmpty(textBox5.Text))
        {
            if (Int32.TryParse(textBox5.Text, out i))
            {
                temptb = textBox5.Text;
            }
            else
            {
                textBox5.Text = temptb;
            }
        }
        else
        {
            temptb = "";
        }
    
        textBox5.SelectionStart = textBox5.Text.Length;
    }


    • Edited by servy42 Tuesday, June 26, 2012 2:53 PM
    • Marked as answer by Lisa Zhu Tuesday, July 3, 2012 7:51 AM
    Tuesday, June 26, 2012 2:50 PM

All replies

  • This example is for an event handler that immediately validates all keypress to be a digit. It uses Regular Expression to do that.

    private void txtBox_KeyPress(object sender, KeyPressEventArgs e)
    {
    if (!System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar.ToString(), "\\d+")) e.Handled = true;
    
    }



    JP Cowboy Coders Unite!


    Monday, June 25, 2012 10:43 PM
  • Use a MaskedTextBox in Windows Forms.

    http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask.aspx   

    I am not aware of an equivalent type in WPF, although WinForms can be used in WPF.

    http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask.aspx  

    That is a 3rd party control made for WPF.  It appears to be highly regarded.

    Or, you could create your own control class in code.  I would suggest that you do it by inheriting from TextBox class.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Monday, June 25, 2012 11:02 PM
  • I would use a KeyPress event:

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
          //allows backspace key
          if (e.KeyChar != '\b')
          {
            //allows just number keys
            e.Handled = !char.IsNumber(e.KeyChar);
          }
        }


    Mitja

    • Marked as answer by Lisa Zhu Tuesday, July 3, 2012 7:42 AM
    Tuesday, June 26, 2012 12:12 AM
  • I would use a KeyPress event:

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
          //allows backspace key
          if (e.KeyChar != '\b')
          {
            //allows just number keys
            e.Handled = !char.IsNumber(e.KeyChar);
          }
        }


    Mitja

    What about minus signs, commas and decimal characters?

    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Tuesday, June 26, 2012 1:23 AM
  • Hi, 

    You can extend TextBox that allows only numerics like, 

    public class NumericalTextBox : TextBox
    	{
    		protected override void OnKeyPress(KeyPressEventArgs e)
    		{
    			if (((char.IsNumber(e.KeyChar))) || (((int)e.KeyChar) == 8) || (((int)e.KeyChar) == 46))
    			{
    				return;
    			}
    			e.Handled = true;
    		}
    	}
    Hope this helps you...


    If this post answers your question, please click "Mark As Answer". If this post is helpful please click "Mark as Helpful".

    • Marked as answer by Lisa Zhu Tuesday, July 3, 2012 7:48 AM
    Tuesday, June 26, 2012 2:01 AM
  • Mitja Bonca's function is successful,you can try!
    Tuesday, June 26, 2012 4:28 AM
  • Hello,

    You can do something like that to handle the signs/separators properly.

    using System.Linq;
    	using System.Globalization;
    	using System.Windows.Forms;
    
    	public partial class AppMain : Form
    	{
    		private readonly NumberFormatInfo numberFormatInfo = CultureInfo.CurrentCulture.NumberFormat;
    
    		private readonly char[] signs;
    
    		public AppMain()
    		{
    			InitializeComponent();
    
    			signs = new[]
    			{
    				char.Parse(numberFormatInfo.NumberDecimalSeparator),
    				char.Parse(numberFormatInfo.NumberGroupSeparator),
    				char.Parse(numberFormatInfo.NegativeSign)
    			};
    
    			textBox1.KeyPress += TextBox1KeyPress;
    		}
    
    		private void TextBox1KeyPress(object sender, KeyPressEventArgs e)
    		{
    			bool exists = signs.Any(ch => e.KeyChar == ch);
    
    			if (exists || e.KeyChar >= 48 && e.KeyChar <= 57 || e.KeyChar == 8)
    			{
    				return;
    			}
    
    			e.Handled = true;
    		}
    	}

    P.s if you don't like/understand/whatever LINQ you can change "signs.Any(ch => e.KeyChar == ch);" to "Array.Exists(signs, ch => e.KeyChar == ch);" -- A subtle difference. :)

    Mitja Bonca's function is successful,you can try!

    I share your excitement, it happens to me too but please, the next time you post make sure you take the time and write something more constructive.


    Eyal (http://shilony.net), Regards.

    • Edited by Eyal Solnik Tuesday, June 26, 2012 4:47 AM
    • Marked as answer by Lisa Zhu Tuesday, July 3, 2012 7:49 AM
    Tuesday, June 26, 2012 4:31 AM
  • try this 

    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (!char.IsControl(e.KeyChar) 
            && !char.IsDigit(e.KeyChar) 
            && e.KeyChar != '.')
        {
            e.Handled = true;
        }
    
        // only allow one decimal point
        if (e.KeyChar == '.' 
            && (sender as TextBox).Text.IndexOf('.') > -1)
        {
            e.Handled = true;
        }
    }

    good luck

    • Marked as answer by Lisa Zhu Tuesday, July 3, 2012 7:49 AM
    Tuesday, June 26, 2012 4:44 AM
  • Guys the problem with most solutions here is that you don't take culture into account and so it might not work for the OP.

    For example to mark the radix point in Spain they tend to use comma character whereas in Israel, UK and the US (not sure about Canada) the point character is used instead.


    Eyal (http://shilony.net), Regards.




    Tuesday, June 26, 2012 5:02 AM
  • What about minus signs, commas and decimal characters?

         Is there any word about negative and decimal numbers?

    According to his statements and code, he for sure only want to have "full" numbers, so Integers, but Im not so sure about negative numbers. 

    I guess if he would have wanted a negative (- infront) he would had said that too.

    ---

    So to allow negative numbers he can do:

            private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
            {
                if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '-')
                    e.Handled = true;
                // only allow negative point (only infront of the number, at index[0]
                if (e.KeyChar == '-' && (sender as TextBox).Text.IndexOf('-') > -1)
                    e.Handled = true;
            }

    Mitja

    Tuesday, June 26, 2012 5:49 AM
  • Sorry for not being clear in my question. I am only looking for positive integers, no decimals, nothing less then 1.
    Tuesday, June 26, 2012 6:43 AM
  •      Is there any word about negative and decimal numbers?
    True. :)

    Sorry for not being clear in my question. I am only looking for positive integers, no decimals, nothing less then 1.
    Well we gave you plenty of examples. :)
    Eyal (http://shilony.net), Regards.
    Tuesday, June 26, 2012 6:50 AM
  • When folks ask for "numbers", I assume that means numerical values.

    When folks ask for "digits", I assume that means numerical characters.


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Tuesday, June 26, 2012 2:23 PM
  • Sorry for not being clear in my question. I am only looking for positive integers, no decimals, nothing less then 1.

    Then use the code I pasted in my 1st post up above, or someone elses. There is plenty of working code for you. But use KeyPress event, not TextChanged, like you did.


    Mitja

    Tuesday, June 26, 2012 2:27 PM
  • Then use the code I pasted in my 1st post up above, or someone elses. There is plenty of working code for you. But use KeyPress event, not TextChanged, like you did.

    It's actually important to use TextChanged, not KeyPress, for sanitizing input like this.

    When running your code do the following:

    1. Highlight the following: "Not a number!"
    2. Copy it to your clipboard.
    3. Right click on the textbox that should only be allowed to be a number.
    4. Select Paste.

    Your 'numeric only' textbox now says, "Not a number!".

    @OP, your code is quite good.  To be honest, it's better than all of the suggestions I've seen here.  If you want the user to be able to delete all of the characters you only need to add an additional "if" so that you don't even try to parse the textbox if it's empty.  See code below:

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        int i;
    
        textBox5.Text = textBox5.Text.Trim();
    
        if (!string.IsNullOrEmpty(textBox5.Text))
        {
            if (Int32.TryParse(textBox5.Text, out i))
            {
                temptb = textBox5.Text;
            }
            else
            {
                textBox5.Text = temptb;
            }
        }
        else
        {
            temptb = "";
        }
    
        textBox5.SelectionStart = textBox5.Text.Length;
    }


    • Edited by servy42 Tuesday, June 26, 2012 2:53 PM
    • Marked as answer by Lisa Zhu Tuesday, July 3, 2012 7:51 AM
    Tuesday, June 26, 2012 2:50 PM
  • Of course you can simply add your own IsNumeric method like so

     private Boolean IsNumeric(Object expression)
            {
                Boolean isNumeric;
                Double numericValue;
                isNumeric = Double.TryParse(Convert.ToString(expression),
                                            System.Globalization.NumberStyles.Any,
                                            System.Globalization.NumberFormatInfo.InvariantInfo,
                                            out numericValue);
                return isNumeric;
            }


    John Grove, Senior Software Engineer http://www.digitizedschematic.com/

    Tuesday, June 26, 2012 3:03 PM