我有一个windows窗体应用程序与一个文本框控件,我想只接受整数值。在过去,我通过重载KeyPress事件并删除不符合规范的字符来进行这种验证。我已经看了MaskedTextBox控件,但我想一个更通用的解决方案,可以与也许正则表达式,或依赖于其他控件的值。
理想情况下,按下非数字字符要么不产生结果,要么立即向用户提供关于无效字符的反馈。
我有一个windows窗体应用程序与一个文本框控件,我想只接受整数值。在过去,我通过重载KeyPress事件并删除不符合规范的字符来进行这种验证。我已经看了MaskedTextBox控件,但我想一个更通用的解决方案,可以与也许正则表达式,或依赖于其他控件的值。
理想情况下,按下非数字字符要么不产生结果,要么立即向用户提供关于无效字符的反馈。
当前回答
在我们的网页与文本框的定义,我们可以添加一个onkeypress事件只接受数字。它不会显示任何消息,但它将防止您输入错误。它为我工作,用户不能输入任何除了数字。
<asp:TextBox runat="server" ID="txtFrom"
onkeypress="if(isNaN(String.fromCharCode(event.keyCode))) return false;">
其他回答
在按钮点击,你可以检查文本框的文本循环:
char[] c = txtGetCustomerId.Text.ToCharArray();
bool IsDigi = true;
for (int i = 0; i < c.Length; i++)
{
if (c[i] < '0' || c[i] > '9')
{ IsDigi = false; }
}
if (IsDigi)
{
// do something
}
这可能有用。它允许“真实”数值,包括正确的小数点和前面的加号或减号。从相关的KeyPress事件中调用它。
private bool IsOKForDecimalTextBox(char theCharacter, TextBox theTextBox)
{
// Only allow control characters, digits, plus and minus signs.
// Only allow ONE plus sign.
// Only allow ONE minus sign.
// Only allow the plus or minus sign as the FIRST character.
// Only allow ONE decimal point.
// Do NOT allow decimal point or digits BEFORE any plus or minus sign.
if (
!char.IsControl(theCharacter)
&& !char.IsDigit(theCharacter)
&& (theCharacter != '.')
&& (theCharacter != '-')
&& (theCharacter != '+')
)
{
// Then it is NOT a character we want allowed in the text box.
return false;
}
// Only allow one decimal point.
if (theCharacter == '.'
&& theTextBox.Text.IndexOf('.') > -1)
{
// Then there is already a decimal point in the text box.
return false;
}
// Only allow one minus sign.
if (theCharacter == '-'
&& theTextBox.Text.IndexOf('-') > -1)
{
// Then there is already a minus sign in the text box.
return false;
}
// Only allow one plus sign.
if (theCharacter == '+'
&& theTextBox.Text.IndexOf('+') > -1)
{
// Then there is already a plus sign in the text box.
return false;
}
// Only allow one plus sign OR minus sign, but not both.
if (
(
(theCharacter == '-')
|| (theCharacter == '+')
)
&&
(
(theTextBox.Text.IndexOf('-') > -1)
||
(theTextBox.Text.IndexOf('+') > -1)
)
)
{
// Then the user is trying to enter a plus or minus sign and
// there is ALREADY a plus or minus sign in the text box.
return false;
}
// Only allow a minus or plus sign at the first character position.
if (
(
(theCharacter == '-')
|| (theCharacter == '+')
)
&& theTextBox.SelectionStart != 0
)
{
// Then the user is trying to enter a minus or plus sign at some position
// OTHER than the first character position in the text box.
return false;
}
// Only allow digits and decimal point AFTER any existing plus or minus sign
if (
(
// Is digit or decimal point
char.IsDigit(theCharacter)
||
(theCharacter == '.')
)
&&
(
// A plus or minus sign EXISTS
(theTextBox.Text.IndexOf('-') > -1)
||
(theTextBox.Text.IndexOf('+') > -1)
)
&&
// Attempting to put the character at the beginning of the field.
theTextBox.SelectionStart == 0
)
{
// Then the user is trying to enter a digit or decimal point in front of a minus or plus sign.
return false;
}
// Otherwise the character is perfectly fine for a decimal value and the character
// may indeed be placed at the current insertion position.
return true;
}
Here is a simple solution that works for me.
public static bool numResult;
public static bool checkTextisNumber(string numberVal)
{
try
{
if (numberVal.Equals("."))
{
numResult = true;
}
else if (numberVal.Equals(""))
{
numResult = true;
}
else
{
decimal number3 = 0;
bool canConvert = decimal.TryParse(numberVal, out number3);
if (canConvert == true)
{
numResult = true;
}
else
numResult = false;
}
}
catch (System.Exception ex)
{
numResult = false;
}
return numResult;
}
string correctNum;
private void tBox_NumTester_TextChanged(object sender, TextChangedEventArgs e)
{
if(checkTextisNumber(tBox_NumTester.Text))
{
correctNum = tBox_NumTester.Text;
}
else
{
tBox_NumTester.Text = correctNum;
}
}
只是因为在一条线上做事情总是更有趣……
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
}
注意:这并不阻止用户复制/粘贴到此文本框。这并不是清除数据的安全方法。
这是一个简单的独立的Winforms自定义控件,从标准的TextBox派生而来,只允许System。Int32输入(它可以很容易地适用于其他类型,如System。Int64,等等)。它支持复制/粘贴操作和负数:
public class Int32TextBox : TextBox
{
protected override void OnKeyPress(KeyPressEventArgs e)
{
base.OnKeyPress(e);
NumberFormatInfo fi = CultureInfo.CurrentCulture.NumberFormat;
string c = e.KeyChar.ToString();
if (char.IsDigit(c, 0))
return;
if ((SelectionStart == 0) && (c.Equals(fi.NegativeSign)))
return;
// copy/paste
if ((((int)e.KeyChar == 22) || ((int)e.KeyChar == 3))
&& ((ModifierKeys & Keys.Control) == Keys.Control))
return;
if (e.KeyChar == '\b')
return;
e.Handled = true;
}
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int WM_PASTE = 0x0302;
if (m.Msg == WM_PASTE)
{
string text = Clipboard.GetText();
if (string.IsNullOrEmpty(text))
return;
if ((text.IndexOf('+') >= 0) && (SelectionStart != 0))
return;
int i;
if (!int.TryParse(text, out i)) // change this for other integer types
return;
if ((i < 0) && (SelectionStart != 0))
return;
}
base.WndProc(ref m);
}
2017年更新:我的第一个答案有一些问题:
你可以输入一个比给定类型的整数更长的值(例如2147483648大于Int32.MaxValue); 更一般地说,对于输入的结果没有真正的验证; 它只处理int32,你必须写特定的TextBox衍生控件为每种类型(Int64等)
所以我提出了另一个更通用的版本,它仍然支持复制/粘贴,+和-号等。
public class ValidatingTextBox : TextBox
{
private string _validText;
private int _selectionStart;
private int _selectionEnd;
private bool _dontProcessMessages;
public event EventHandler<TextValidatingEventArgs> TextValidating;
protected virtual void OnTextValidating(object sender, TextValidatingEventArgs e) => TextValidating?.Invoke(sender, e);
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (_dontProcessMessages)
return;
const int WM_KEYDOWN = 0x100;
const int WM_ENTERIDLE = 0x121;
const int VK_DELETE = 0x2e;
bool delete = m.Msg == WM_KEYDOWN && (int)m.WParam == VK_DELETE;
if ((m.Msg == WM_KEYDOWN && !delete) || m.Msg == WM_ENTERIDLE)
{
DontProcessMessage(() =>
{
_validText = Text;
_selectionStart = SelectionStart;
_selectionEnd = SelectionLength;
});
}
const int WM_CHAR = 0x102;
const int WM_PASTE = 0x302;
if (m.Msg == WM_CHAR || m.Msg == WM_PASTE || delete)
{
string newText = null;
DontProcessMessage(() =>
{
newText = Text;
});
var e = new TextValidatingEventArgs(newText);
OnTextValidating(this, e);
if (e.Cancel)
{
DontProcessMessage(() =>
{
Text = _validText;
SelectionStart = _selectionStart;
SelectionLength = _selectionEnd;
});
}
}
}
private void DontProcessMessage(Action action)
{
_dontProcessMessages = true;
try
{
action();
}
finally
{
_dontProcessMessages = false;
}
}
}
public class TextValidatingEventArgs : CancelEventArgs
{
public TextValidatingEventArgs(string newText) => NewText = newText;
public string NewText { get; }
}
对于Int32,你可以从它导出,像这样:
public class Int32TextBox : ValidatingTextBox
{
protected override void OnTextValidating(object sender, TextValidatingEventArgs e)
{
e.Cancel = !int.TryParse(e.NewText, out int i);
}
}
或w/o派生,使用新的textvalididating事件,像这样:
var vtb = new ValidatingTextBox();
...
vtb.TextValidating += (sender, e) => e.Cancel = !int.TryParse(e.NewText, out int i);
但它的优点是它适用于任何字符串和任何验证例程。