Thursday, October 2, 2014

Simple TextBox that only accepts numeric values in C#

Features:
1. Only accepts integers
2. Allows backspace and other control characters
3. Accepts pasted input
4. Rejects pasted input if it's not an integer
5. Protects against invalid data type by initializing to 0 and disallowing empty strings -- thus you don't have to check before converting to an integer
6. Selects all text automatically if it's 0. This is useful if you don't want to have to manually select all to type over the 0

References
1. http://msdn.microsoft.com/en-us/library/ms229644(v=vs.80).aspx
2. http://stackoverflow.com/questions/463299/how-do-i-make-a-textbox-that-only-accepts-numbers
3. http://stackoverflow.com/questions/15772602/how-to-undo-and-redo-in-c-sharp-rich-text-box
4. Async select all on enter http://stackoverflow.com/a/6857301/1538717

Code
  1.     public class NumericTextBox : TextBox
  2.     {
  3.         private string lastGoodValue = "";
  4.         protected override void OnKeyPress(KeyPressEventArgs e)
  5.         {
  6.             base.OnKeyPress(e);
  7.  
  8.             if (Char.IsDigit(e.KeyChar)  || e.KeyChar == '\b' || Char.IsControl(e.KeyChar) || isPaste(e))
  9.             { }
  10.             else
  11.             {
  12.                 e.Handled = true;
  13.             }
  14.         }
  15.  
  16.         private bool isPaste(KeyPressEventArgs e)
  17.         {
  18.             if ((((int)e.KeyChar == 22) || ((int)e.KeyChar == 3))
  19.             && ((ModifierKeys & Keys.Control) == Keys.Control))
  20.                 return true;
  21.             return false;
  22.         }
  23.  
  24.         protected override void OnValidating(System.ComponentModel.CancelEventArgs e)
  25.         {
  26.             base.OnValidating(e);
  27.             setTextTo0IfEmpty();
  28.         }
  29.         protected override void OnTextChanged(EventArgs e)
  30.         {
  31.             base.OnTextChanged(e);
  32.             setTextTo0IfEmpty();
  33.             int dummy;
  34.             if (!Int32.TryParse(Text, out dummy))
  35.                 resetToLastGoodValue();
  36.             lastGoodValue = Text;
  37.  
  38.         }
  39.  
  40.         private void resetToLastGoodValue()
  41.         {
  42.             Text = lastGoodValue;
  43.             Select(Text.Length0); //otherwise the cursor goes to the beginning of the textbox
  44.         }
  45.  
  46.         private void setTextTo0IfEmpty()
  47.         {
  48.             if (Text == "")
  49.             {
  50.                 Text = "0";
  51.                 SelectAll(); //otherwise you have to manually select the 0 to type over it
  52.                
  53.             }
  54.         }
  55.         private void AsyncSelectAll()
  56.         {
  57.             BeginInvoke((Action)delegate
  58.             {
  59.                 SelectAll();
  60.             });
  61.         }
  62.         public NumericTextBox() : base()
  63.         {
  64.             setTextTo0IfEmpty();
  65.         }
  66.         protected override void OnEnter(EventArgs e)
  67.         {
  68.             if (Text == "0")
  69.                 AsyncSelectAll();
  70.         }
  71.  
  72.         public int IntValue
  73.         {
  74.             get
  75.             {
  76.                 return Int32.Parse(this.Text);
  77.             }
  78.         }
  79.     }

No comments:

Post a Comment

There was an error in this gadget