两种选择:
请改用 NumericUpDown。 NumericUpDown 为您进行过滤,这很好。当然,它还使您的用户能够点击键盘上的向上和向下箭头来增加和减少当前值。处理适当的键盘事件以防止除数字输入之外的任何内容。我在标准 TextBox 上使用这两个事件处理程序取得了成功: private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && (e .KeyChar != '.')) { e.Handled = true; } // 只允许一位小数 if ((e.KeyChar == '.') && ((sender as TextBox).Text.IndexOf('.') > -1)) { e.Handled = true; } }
如果您的 TextBox 不允许使用小数位,您可以删除对 '.'
的检查(以及对多个 '.'
的后续检查)。如果您的 TextBox 应该允许负值,您还可以添加对 '-'
的检查。
如果要限制用户的位数,请使用:textBox1.MaxLength = 2; // this will allow the user to enter only 2 digits
仅仅因为在一行中做事总是更有趣……
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
}
注意:这不会阻止用户复制/粘贴到此文本框中。这不是清理数据的万无一失的方法。
KeyPress
事件时,这可能不起作用。一个事件可能会将 e.Handled
设置为 true,然后另一个事件会将其设置回 false。一般来说,最好使用 if (...) e.Handled = true;
TextChanged
事件可以修复复制粘贴;)
我从上下文和您使用的标签假设您正在编写一个 .NET C# 应用程序。在这种情况下,您可以订阅文本更改事件,并验证每个击键。
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (System.Text.RegularExpressions.Regex.IsMatch(textBox1.Text, "[^0-9]"))
{
MessageBox.Show("Please enter only numbers.");
textBox1.Text = textBox1.Text.Remove(textBox1.Text.Length - 1);
}
}
textBox1.Text = textBox1.Text.Remove(textBox1.Text.Length - 1);
这是一个简单的独立 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,您必须为每种类型(Int64 等)编写特定的 TextBox 派生控件
所以我想出了另一个更通用的版本,它仍然支持复制/粘贴、+ 和 - 符号等。
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);
}
}
或没有派生,使用新的 TextValidating 事件,如下所示:
var vtb = new ValidatingTextBox();
...
vtb.TextValidating += (sender, e) => e.Cancel = !int.TryParse(e.NewText, out int i);
但好的是它适用于任何字符串和任何验证例程。
这正是 Validated/Validating 事件的设计目的。
这是有关该主题的 MSDN 文章:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validating.aspx
TL;DR 版本:检查 Validating 事件中的 .Text 属性,并在数据无效时设置 e.Cancel=True
。
当您设置 e.Cancel=True 时,用户不能离开该字段,但您需要向他们提供某种反馈,表明有问题。我将框的背景颜色更改为浅红色以表示存在问题。确保在以良好值调用 Validating 时将其设置回 SystemColors.Window
。
Validating
的特定文档指针。 <nitpick>
OP 提到立即禁止/指示无效字符是理想的,但 Validating
似乎需要在其生效之前将焦点移至另一个表单/控件。</nitpick>
不过,这是一个很好的方法,并且总是在更一般的情况下值得考虑。
试试 MaskedTextBox。它采用简单的掩码格式,因此您可以将输入限制为数字或日期等。
您可以使用 TextChanged
事件
private void textBox_BiggerThan_TextChanged(object sender, EventArgs e)
{
long a;
if (! long.TryParse(textBox_BiggerThan.Text, out a))
{
// If not int clear textbox text or Undo() last operation
textBox_LessThan.Clear();
}
}
Undo()
,它看起来应该可以正常工作,但它会导致 StackOverflowException
。
public int txtBoxValue
,如果 tryParse 不起作用,我会通过 txtBox.Text = txtBoxValue.ToString();
恢复 txtBox 中的文本
这可能很有用。它允许“真实”数值,包括正确的小数点和前面的加号或减号。从相关的 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;
}
只需使用 NumericUpDown
控件并将那些难看的向上向下按钮的可见性设置为 false
。
numericUpDown1.Controls[0].Visible = false;
NumericUpDown
实际上是一个控件集合,其中包含一个“旋转框”(向上向下按钮)、一个文本框和一些用于验证和将它们组合在一起的代码。
标记:
YourNumericUpDown.Controls[0].visible = false
将隐藏按钮,同时保持底层代码处于活动状态。
虽然不是一个明显的解决方案,但它既简单又有效。如果您想这样做,.Controls[1]
会隐藏文本框部分。
我一直在研究一组组件来完成 WinForms 中缺少的东西,这里是:Advanced Forms
特别是这是 Regex TextBox 的类
/// <summary>Represents a Windows text box control that only allows input that matches a regular expression.</summary>
public class RegexTextBox : TextBox
{
[NonSerialized]
string lastText;
/// <summary>A regular expression governing the input allowed in this text field.</summary>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual Regex Regex { get; set; }
/// <summary>A regular expression governing the input allowed in this text field.</summary>
[DefaultValue(null)]
[Category("Behavior")]
[Description("Sets the regular expression governing the input allowed for this control.")]
public virtual string RegexString {
get {
return Regex == null ? string.Empty : Regex.ToString();
}
set {
if (string.IsNullOrEmpty(value))
Regex = null;
else
Regex = new Regex(value);
}
}
protected override void OnTextChanged(EventArgs e) {
if (Regex != null && !Regex.IsMatch(Text)) {
int pos = SelectionStart - Text.Length + (lastText ?? string.Empty).Length;
Text = lastText;
SelectionStart = Math.Max(0, pos);
}
lastText = Text;
base.OnTextChanged(e);
}
}
只需添加类似 myNumbericTextBox.RegexString = "^(\\d+|)$";
的内容就足够了。
只需在文本框中使用此代码:
private void textBox1_TextChanged(object sender, EventArgs e)
{
double parsedValue;
if (!double.TryParse(textBox1.Text, out parsedValue))
{
textBox1.Text = "";
}
}
我在 CodePlex 上为此做了一些事情。
它通过拦截 TextChanged 事件来工作。如果结果是一个好的数字,它将被存储。如果出现问题,将恢复最后的良好值。源代码有点太大,无法在此处发布,但 here is a link to the class 处理了此逻辑的核心。
在我们定义了文本框的网页中,我们可以添加一个 onkeypress
事件来仅接受数字。它不会显示任何消息,但会防止您输入错误。它对我有用,用户只能输入数字。
<asp:TextBox runat="server" ID="txtFrom"
onkeypress="if(isNaN(String.fromCharCode(event.keyCode))) return false;">
整数和浮点数都需要接受,包括负数。
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
// Text
string text = ((Control) sender).Text;
// Is Negative Number?
if (e.KeyChar == '-' && text.Length == 0)
{
e.Handled = false;
return;
}
// Is Float Number?
if (e.KeyChar == '.' && text.Length > 0 && !text.Contains("."))
{
e.Handled = false;
return;
}
// Is Digit?
e.Handled = (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar));
}
这是我的方法:
使用 linq(易于修改过滤器)复制/粘贴证明代码在您按下禁止字符时保持插入位置接受左零和任何大小的数字 private void numeroCuenta_TextChanged(object sender, EventArgs e) { string org = numeroCuenta.Text;格式化字符串 = string.Concat(org.Where(c => (c >= '0' && c <= '9')));如果(格式化!= org){ int s = numeroCuenta.SelectionStart; if (s > 0 && formated.Length > s && org[s - 1] != formated[s - 1]) s--; numeroCuenta.Text = 格式化; numeroCuenta.SelectionStart = s; } }
这是使用 .NET 5/Core 实现此目的的一种简便快捷的方法
private void textBox1_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyData != Keys.Back)
e.SuppressKeyPress = !int.TryParse(Convert.ToString((char) e.KeyData), out int _);
}
编辑:添加了对退格键的支持
我会在 KeyDown 事件中处理它。
void TextBox_KeyDown(object sender, KeyEventArgs e)
{
char c = Convert.ToChar(e.PlatformKeyCode);
if (!char.IsDigit(c))
{
e.Handled = true;
}
}
private void txt3_KeyPress(object sender, KeyPressEventArgs e)
{
for (int h = 58; h <= 127; h++)
{
if (e.KeyChar == h) //58 to 127 is alphabets tat will be blocked
{
e.Handled = true;
}
}
for(int k=32;k<=47;k++)
{
if (e.KeyChar == k) //32 to 47 are special characters tat will
{ be blocked
e.Handled = true;
}
}
}
试试这个很简单
我已经发布了我的解决方案,它在文本框中使用 ProcessCmdKey 和 OnKeyPress 事件。评论向您展示了如何使用正则表达式来验证按键并适当地阻止/允许。
嗨,您可以在文本框的 textchanged 事件中执行类似的操作。
这是一个演示
private void textBox1_TextChanged(object sender, EventArgs e)
{
string actualdata = string.Empty;
char[] entereddata = textBox1.Text.ToCharArray();
foreach (char aChar in entereddata.AsEnumerable())
{
if (Char.IsDigit(aChar))
{
actualdata = actualdata + aChar;
// MessageBox.Show(aChar.ToString());
}
else
{
MessageBox.Show(aChar + " is not numeric");
actualdata.Replace(aChar, ' ');
actualdata.Trim();
}
}
textBox1.Text = actualdata;
}
似乎这个问题的许多当前答案都是手动解析输入文本。如果您正在寻找特定的内置数字类型(例如 int
或 double
),为什么不将工作委托给该类型的 TryParse
方法呢?例如:
public class IntTextBox : TextBox
{
string PreviousText = "";
int BackingResult;
public IntTextBox()
{
TextChanged += IntTextBox_TextChanged;
}
public bool HasResult { get; private set; }
public int Result
{
get
{
return HasResult ? BackingResult : default(int);
}
}
void IntTextBox_TextChanged(object sender, EventArgs e)
{
HasResult = int.TryParse(Text, out BackingResult);
if (HasResult || string.IsNullOrEmpty(Text))
{
// Commit
PreviousText = Text;
}
else
{
// Revert
var changeOffset = Text.Length - PreviousText.Length;
var previousSelectionStart =
Math.Max(0, SelectionStart - changeOffset);
Text = PreviousText;
SelectionStart = previousSelectionStart;
}
}
}
如果您想要更通用但仍与 Visual Studio 的设计器兼容的东西:
public class ParsableTextBox : TextBox
{
TryParser BackingTryParse;
string PreviousText = "";
object BackingResult;
public ParsableTextBox()
: this(null)
{
}
public ParsableTextBox(TryParser tryParse)
{
TryParse = tryParse;
TextChanged += ParsableTextBox_TextChanged;
}
public delegate bool TryParser(string text, out object result);
public TryParser TryParse
{
set
{
Enabled = !(ReadOnly = value == null);
BackingTryParse = value;
}
}
public bool HasResult { get; private set; }
public object Result
{
get
{
return GetResult<object>();
}
}
public T GetResult<T>()
{
return HasResult ? (T)BackingResult : default(T);
}
void ParsableTextBox_TextChanged(object sender, EventArgs e)
{
if (BackingTryParse != null)
{
HasResult = BackingTryParse(Text, out BackingResult);
}
if (HasResult || string.IsNullOrEmpty(Text))
{
// Commit
PreviousText = Text;
}
else
{
// Revert
var changeOffset = Text.Length - PreviousText.Length;
var previousSelectionStart =
Math.Max(0, SelectionStart - changeOffset);
Text = PreviousText;
SelectionStart = previousSelectionStart;
}
}
}
最后,如果您想要一些完全通用的东西并且不关心 Designer 支持:
public class ParsableTextBox<T> : TextBox
{
TryParser BackingTryParse;
string PreviousText;
T BackingResult;
public ParsableTextBox()
: this(null)
{
}
public ParsableTextBox(TryParser tryParse)
{
TryParse = tryParse;
TextChanged += ParsableTextBox_TextChanged;
}
public delegate bool TryParser(string text, out T result);
public TryParser TryParse
{
set
{
Enabled = !(ReadOnly = value == null);
BackingTryParse = value;
}
}
public bool HasResult { get; private set; }
public T Result
{
get
{
return HasResult ? BackingResult : default(T);
}
}
void ParsableTextBox_TextChanged(object sender, EventArgs e)
{
if (BackingTryParse != null)
{
HasResult = BackingTryParse(Text, out BackingResult);
}
if (HasResult || string.IsNullOrEmpty(Text))
{
// Commit
PreviousText = Text;
}
else
{
// Revert
var changeOffset = Text.Length - PreviousText.Length;
var previousSelectionStart =
Math.Max(0, SelectionStart - changeOffset);
Text = PreviousText;
SelectionStart = previousSelectionStart;
}
}
}
使用 Fabio Iotti's answer 中描述的方法,我创建了一个更通用的解决方案:
public abstract class ValidatedTextBox : TextBox {
private string m_lastText = string.Empty;
protected abstract bool IsValid(string text);
protected sealed override void OnTextChanged(EventArgs e) {
if (!IsValid(Text)) {
var pos = SelectionStart - Text.Length + m_lastText.Length;
Text = m_lastText;
SelectionStart = Math.Max(0, pos);
}
m_lastText = Text;
base.OnTextChanged(e);
}
}
“ValidatedTextBox”,其中包含所有重要的验证行为。剩下要做的就是从此类继承并使用所需的任何验证逻辑覆盖“IsValid”方法。例如,使用这个类,可以创建“RegexedTextBox”,它只接受匹配特定正则表达式的字符串:
public abstract class RegexedTextBox : ValidatedTextBox {
private readonly Regex m_regex;
protected RegexedTextBox(string regExpString) {
m_regex = new Regex(regExpString);
}
protected override bool IsValid(string text) {
return m_regex.IsMatch(Text);
}
}
之后,继承“RegexedTextBox”类,我们可以轻松创建“PositiveNumberTextBox”和“PositiveFloatingPointNumberTextBox”控件:
public sealed class PositiveNumberTextBox : RegexedTextBox {
public PositiveNumberTextBox() : base(@"^\d*$") { }
}
public sealed class PositiveFloatingPointNumberTextBox : RegexedTextBox {
public PositiveFloatingPointNumberTextBox()
: base(@"^(\d+\" + CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator + @")?\d*$") { }
}
很抱歉唤醒死者,但我想有人可能会发现这对将来的参考很有用。
这是我的处理方式。它处理浮点数,但可以很容易地修改为整数。
基本上你只能按 0 - 9 和 .
之前只能有一个 0。
忽略所有其他字符并保持光标位置。
private bool _myTextBoxChanging = false;
private void myTextBox_TextChanged(object sender, EventArgs e)
{
validateText(myTextBox);
}
private void validateText(TextBox box)
{
// stop multiple changes;
if (_myTextBoxChanging)
return;
_myTextBoxChanging = true;
string text = box.Text;
if (text == "")
return;
string validText = "";
bool hasPeriod = false;
int pos = box.SelectionStart;
for (int i = 0; i < text.Length; i++ )
{
bool badChar = false;
char s = text[i];
if (s == '.')
{
if (hasPeriod)
badChar = true;
else
hasPeriod = true;
}
else if (s < '0' || s > '9')
badChar = true;
if (!badChar)
validText += s;
else
{
if (i <= pos)
pos--;
}
}
// trim starting 00s
while (validText.Length >= 2 && validText[0] == '0')
{
if (validText[1] != '.')
{
validText = validText.Substring(1);
if (pos < 2)
pos--;
}
else
break;
}
if (pos > validText.Length)
pos = validText.Length;
box.Text = validText;
box.SelectionStart = pos;
_myTextBoxChanging = false;
}
这是一个快速修改的 int 版本:
private void validateText(TextBox box)
{
// stop multiple changes;
if (_myTextBoxChanging)
return;
_myTextBoxChanging = true;
string text = box.Text;
if (text == "")
return;
string validText = "";
int pos = box.SelectionStart;
for (int i = 0; i < text.Length; i++ )
{
char s = text[i];
if (s < '0' || s > '9')
{
if (i <= pos)
pos--;
}
else
validText += s;
}
// trim starting 00s
while (validText.Length >= 2 && validText.StartsWith("00"))
{
validText = validText.Substring(1);
if (pos < 2)
pos--;
}
if (pos > validText.Length)
pos = validText.Length;
box.Text = validText;
box.SelectionStart = pos;
_myTextBoxChanging = false;
}
这个适用于复制和粘贴,拖放,按键,防止溢出并且非常简单
public partial class IntegerBox : TextBox
{
public IntegerBox()
{
InitializeComponent();
this.Text = 0.ToString();
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
private String originalValue = 0.ToString();
private void Integerbox_KeyPress(object sender, KeyPressEventArgs e)
{
originalValue = this.Text;
}
private void Integerbox_TextChanged(object sender, EventArgs e)
{
try
{
if(String.IsNullOrWhiteSpace(this.Text))
{
this.Text = 0.ToString();
}
this.Text = Convert.ToInt64(this.Text.Trim()).ToString();
}
catch (System.OverflowException)
{
MessageBox.Show("Value entered is to large max value: " + Int64.MaxValue.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
this.Text = originalValue;
}
catch (System.FormatException)
{
this.Text = originalValue;
}
catch (System.Exception ex)
{
this.Text = originalValue;
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK , MessageBoxIcon.Error);
}
}
}
不要忘记用户可以在 TextBox
中粘贴无效文本。
如果你想限制它,请按照以下代码:
private void ultraTextEditor1_TextChanged(object sender, EventArgs e)
{
string append="";
foreach (char c in ultraTextEditor1.Text)
{
if ((!Char.IsNumber(c)) && (c != Convert.ToChar(Keys.Back)))
{
}
else
{
append += c;
}
}
ultraTextEditor1.Text = append;
}
我也在寻找仅检查文本框中数字的最佳方法,而按键的问题是它不支持通过右键单击或剪贴板进行复制粘贴,因此提出了此代码,该代码验证光标何时离开文本字段并检查空字段。 (新人改编版)
private void txtFirstValue_MouseLeave(object sender, EventArgs e)
{
int num;
bool isNum = int.TryParse(txtFirstValue.Text.Trim(), out num);
if (!isNum && txtFirstValue.Text != String.Empty)
{
MessageBox.Show("The First Value You Entered Is Not a Number, Please Try Again", "Invalid Value Detected", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtFirstValue.Clear();
}
}
这里有30多个答案,很多答案很有帮助。但我想为 System.Windows.Forms.TextBox 和 System.Windows.Controls.TextBox 共享一个通用表单。
System.Windows.Controls.TextBox 中没有可用的 KeyPress 事件。这个答案适用于那些想要为 System.Windows.Forms.TextBox 和 System.Windows.Controls.TextBox 实现相同逻辑的人。
这是 NumberTextBox 代码。使用注释行代替 System.Windows.Controls.TextBox 的前一行。
public class NumberTextBox : System.Windows.Forms.TextBox
//public class NumberTextBox : System.Windows.Controls.TextBox
{
private double _maxValue;
private double _minValue;
private bool _flag;
private string _previousValue;
public NumberTextBox()
{
this.TextAlign = HorizontalAlignment.Right;
//TextAlignment = TextAlignment.Right;
KeyDown += TextBox_KeyDown;
TextChanged += TextBox_TextChanged;
_minValue = double.MinValue;
_maxValue = double.MaxValue;
}
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
_previousValue = this.Text;
_flag = this.SelectedText.Length > 0;
}
private void TextBox_TextChanged(object sender, EventArgs e)
//private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var text = this.Text;
if (text.Length < 1) return;
var cursorPosition = SelectionStart == 0 ? SelectionStart : SelectionStart - 1;
var insertedChar = text[cursorPosition];
if (IsInvalidInput(insertedChar, cursorPosition, text))
{
HandleText(text, cursorPosition);
}
ValidateRange(text, cursorPosition);
}
private bool IsInvalidInput(char insertedChar, int cursorPosition, string text)
{
return !char.IsDigit(insertedChar) && insertedChar != '.' && insertedChar != '-' ||
insertedChar == '-' && cursorPosition != 0 ||
text.Count(x => x == '.') > 1 ||
text.Count(x => x == '-') > 1;
}
private void HandleText(string text, int cursorPosition)
{
this.Text = _flag ? _previousValue : text.Remove(cursorPosition, 1);
this.SelectionStart = cursorPosition;
this.SelectionLength = 0;
}
private void ValidateRange(string text, int cursorPosition)
{
try
{
if (text == "." || _minValue < 0 && text == "-") return;
var doubleValue = Convert.ToDouble(text);
if (doubleValue > _maxValue || doubleValue < _minValue)
{
HandleText(text, cursorPosition);
}
}
catch (Exception)
{
HandleText(text, cursorPosition);
}
}
protected void SetProperties(double minValue = double.MinValue, double maxValue = double.MaxValue)
{
_minValue = minValue;
_maxValue = maxValue;
}
}
PositiveNumberTextBox 代码:
public class PositiveNumberTextBox : NumberTextBox
{
public PositiveNumberTextBox()
{
SetProperties(0);
}
}
分数文本框代码:
public class FractionNumberTextBox : NumberTextBox
{
public FractionNumberTextBox()
{
SetProperties(0, 0.999999);
}
}
int Number;
bool isNumber;
isNumber = int32.TryPase(textbox1.text, out Number);
if (!isNumber)
{
(code if not an integer);
}
else
{
(code if an integer);
}
3 解决方案
1)
//Add to the textbox's KeyPress event
//using Regex for number only textBox
private void txtBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar.ToString(), "\\d+"))
e.Handled = true;
}
2)msdn的另一个解决方案
// Boolean flag used to determine when a character other than a number is entered.
private bool nonNumberEntered = false;
// Handle the KeyDown event to determine the type of character entered into the control.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
// Initialize the flag to false.
nonNumberEntered = false;
// Determine whether the keystroke is a number from the top of the keyboard.
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
{
// Determine whether the keystroke is a number from the keypad.
if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)
{
// Determine whether the keystroke is a backspace.
if (e.KeyCode != Keys.Back)
{
// A non-numerical keystroke was pressed.
// Set the flag to true and evaluate in KeyPress event.
nonNumberEntered = true;
}
}
}
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (nonNumberEntered == true)
{
MessageBox.Show("Please enter number only...");
e.Handled = true;
}
}
来源http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress(v=VS.90).aspx
3) 使用 MaskedTextBox:http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.aspx