Introduction
This tip solves one thing: numeric input only in textbox
in WinForm Application.
And the way applied here can also be adapted to serve other needs.
Actually, we can also use other Windows form controls like numeric updown or MaskedTextbox, or even make our own textbox control (reference: https://msdn.microsoft.com/en-us/library/ms229644(v=vs.100).aspx) to only accept numeric input. This article will also cover these two solutions.
How to Approach
We need to keep an eye on every user input and if the character input is not numeric, we need to delete it.
Thus using event control is a very natural way. One way is to use TextChanged
-- delete the invalid input after it has already been rendered on the textbox
; Either is to use KeyPress
-- we intercept when the key is down which is before rendering onto textbox
.
Writing the Code
Using TextChanged Event
Firstm we add an Event
bound to the textbox
. Here, the name of mine is "tbNumOnly
"
Then, we add this in the event handler here.
(It involves a bit of logic here which is why I do not highly recommend this method.)
private void tbNumOnly_TextChanged(object sender, EventArgs e)
{
try
{
string str = tbNumOnly.Text;
int cursorPos = tbNumOnly.SelectionStart;
if (!char.IsDigit(str[cursorPos - 1]))
{
tbNumOnly.Text = str.Substring(0, cursorPos - 1) + str.Substring(cursorPos);
tbNumOnly.SelectionStart = cursorPos - 1;
tbNumOnly.SelectionLength = 0;
}
}
catch (IndexOutOfRangeException)
{
}
}
It acquires the cursor position in the textbox
first, judges if the character right before the cursor is numeric, discards if not, and finally sets the cursor back to the desired position. If index is out of range, just do nothing.
Using KeyPress Event
private void tbNumOnly_KeyPress(object sender, KeyPressEventArgs e)
{
char ch = e.KeyChar;
if (!char.IsDigit(ch) &&
ch != Convert.ToChar(Keys.Back) &&
ch != Convert.ToChar(Keys.Delete))
e.Handled = true;
}
Here, we just monitor the key user pressed in the textbox
. If it is is not numeric, we artificially set it Handled
hence the key appears as if not yet pressed.
This solution is much easier than the first one.
GOTCHA: Please don't use KeyUp or KeyDown like this: KeyPress
includes KeyUp
and KeyDown
. If KeyDown
is Handled, KeyUp
is still to be handled, hence the non-numeric character will appear on the textbox
. Thus, if you handled KeyPress
, you handled both.
Differences
Solution "TextChanged
" will delete the invalid input automatically, while solution "KeyPress
" will disable any invalid inputs.
Drawbacks
Thanks for the reminding of OriginalGriff these two self-implemented ways don't solve the paste problems. You can right-click on it or control + v virtually anything you want. I figured out one way thanks to Damith at his answers at http://stackoverflow.com/questions/16684406/how-to-disable-the-right-click-context-menu-on-textboxes-in-windows-using-c#16684475. This can disable any right-click context menu or shortcuts, which is nevertheless a bit unconvenient if you have other uses of the textbox.
tbNumOnly.ShortCutsEnabled = false;
Alternatives:
1. Using a numericupdown or mask. They're here:
(also you can find it in All Windows Forms)
Numeric up down is foolproof and For MaskTextbox, we usually set these to easily achieve our goal:
2. "Wrap" a textbox. That is well described as an example in MSDN here: you overriding the basic OnKeyPress() (Keypress event).
You can just paste the two solutions described above into the "OnKeyPress()", after the
base.OnKeyPress(e);
To conclude, making a textbox only accept numeric input entails deleting the invalid input after right at then they input.
Hope these help.