我如何使一个文本框,只接受数字?

我有一个windows窗体应用程序与一个文本框控件,我想只接受整数值。在过去,我通过重载KeyPress事件并删除不符合规范的字符来进行这种验证。我已经看了MaskedTextBox控件,但我想一个更通用的解决方案,可以与也许正则表达式,或依赖于其他控件的值。

理想情况下,按下非数字字符要么不产生结果,要么立即向用户提供关于无效字符的反馈。

1381465 次浏览

你可以使用TextChanged/ Keypress事件,使用正则表达式过滤数字并采取一些行动。

试试MaskedTextBox。它采用一种简单的掩码格式,这样你就可以将输入限制为数字或日期之类的。

我从上下文和您使用的标记假设您正在编写一个。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);
}
}

两个选择:

  1. 使用a NumericUpDown代替。NumericUpDown为你过滤,这很好。当然,它还允许用户点击键盘上的上下箭头来增加和减少当前值。

  2. 处理适当的键盘事件以防止除数字输入以外的任何输入。我已经成功地与这两个事件处理程序在一个标准的文本框:

    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;
    }
    }
    

You can remove the check for '.' (and the subsequent check for more than one '.') if your TextBox shouldn't allow decimal places. You could also add a check for '-' if your TextBox should allow negative values.

If you want to limit the user for number of digit, use: textBox1.MaxLength = 2; // this will allow the user to enter only 2 digits

看看WinForm中的输入处理

我已经发布了我的解决方案,在文本框上使用ProcessCmdKey和OnKeyPress事件。注释向您展示了如何使用Regex来验证键按和适当地阻止/允许。

我在CodePlex上上做了一些东西。

它通过拦截TextChanged事件来工作。如果结果是一个好的数字,它将被存储。如果是错误的,最后的好值将恢复。源代码有点太大,不适合在这里发布,但是这里有一个类的链接处理了这个逻辑的核心。

只是因为在一条线上做事情总是更有趣……

 private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
}

注意:这并不阻止用户复制/粘贴到此文本框。这并不是清除数据的安全方法。

很抱歉吵醒死人,但我想有人可能会觉得这对将来的参考有用。

以下是我的处理方法。它处理浮点数,但可以很容易地修改为整数。

基本上你只能按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;
}
int Number;
bool isNumber;
isNumber = int32.TryPase(textbox1.text, out Number);


if (!isNumber)
{
(code if not an integer);
}
else
{
(code if an integer);
}

您可以使用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();
}
}

这可能有用。它允许“真实”数值,包括正确的小数点和前面的加号或减号。从相关的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;
}

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;
}
< p > 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;
}
}

源# EYZ0

3)使用MaskedTextBox: http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.aspx

这是一个简单的独立的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);

但它的优点是它适用于任何字符串和任何验证例程。

我会在KeyDown事件中处理它。

void TextBox_KeyDown(object sender, KeyEventArgs e)
{
char c = Convert.ToChar(e.PlatformKeyCode);
if (!char.IsDigit(c))
{
e.Handled = true;
}
}

这正是设计已验证/正在验证事件的目的。

下面是MSDN上关于这个主题的文章:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validating.aspx

TL;DR版本:检查validation事件中的. text属性,当数据无效时设置e.Cancel=True

当你设置e.Cancel=True时,用户不能离开这个字段,但是你需要给他们一些错误的反馈。我将方框的背景颜色更改为浅红色,以表示有问题。当使用一个好的值调用valididating时,请确保将其设置回SystemColors.Window

在按钮点击,你可以检查文本框的文本循环:

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
}

这个功能包括复制粘贴,拖放,按下键,防止溢出,非常简单

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.TextChanged += delegate(System.Object o, System.EventArgs e)
{
TextBox _tbox = o as TextBox;
_tbox.Text = new string(_tbox.Text.Where(c => (char.IsDigit(c)) || (c == '.')).ToArray());
};
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;
}
}
}

试试这个很简单

你可以在文本框的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,真的很长!)

public void Check_If_Int_On_TextChanged(object sender, EventArgs e)
{
// This method checks that each inputed character is a number. Any non-numeric
// characters are removed from the text


TextBox textbox = (TextBox)sender;


// If the text is empty, return
if (textbox.Text.Length == 0) { return; }


// Check the new Text value if it's only numbers
byte parsedValue;
if (!byte.TryParse(textbox.Text[(textbox.Text.Length - 1)].ToString(), out parsedValue))
{
// Remove the last character as it wasn't a number
textbox.Text = textbox.Text.Remove((textbox.Text.Length - 1));


// Move the cursor to the end of text
textbox.SelectionStart = textbox.Text.Length;
}
}

似乎目前对这个问题的许多答案都是手动解析输入文本。如果您正在寻找特定的内置数字类型(例如intdouble),为什么不直接将工作委托给该类型的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;
}
}
}

在文本框中简单地使用此代码:

private void textBox1_TextChanged(object sender, EventArgs e)
{


double parsedValue;


if (!double.TryParse(textBox1.Text, out parsedValue))
{
textBox1.Text = "";
}
}

我一直在做一个组件的集合来完成WinForms中缺失的东西,这里是:高级形式

特别地,这是一个正则文本框类

/// <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 xmm_textbox_KeyPress(object sender, KeyPressEventArgs e) {
double x;
e.Handled = !double.TryParse(((TextBox)sender).Text, out x);
}

我也在寻找最好的方法来检查文本框中只有数字和键盘的问题是,它不支持通过右键单击或剪贴板复制粘贴,所以提出了这个代码,验证光标离开文本字段时,它也检查空字段。(newguy改编版)

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();
}
}

在我们的网页文本框的定义中,我们可以添加一个onkeypress事件,只接受数字。它不会显示任何消息,但它将防止您输入错误。它为我工作,用户不能输入任何除了数字。

<asp:TextBox runat="server" ID="txtFrom"
onkeypress="if(isNaN(String.fromCharCode(event.keyCode))) return false;">

不要忘记用户可以在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;
}
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;
}


}

只需使用NumericUpDown控件,并设置那些丑陋的上下按钮可见性为false

numericUpDown1.Controls[0].Visible = false;

NumericUpDown实际上是一个包含“旋转框”(上下按钮)的控件集合,一个文本框和一些代码来验证和wange-jangle。

标记:

YourNumericUpDown.Controls[0].visible = false

将隐藏按钮,同时保持底层代码活动。

虽然不是一个明显的解决方案,但它简单有效。如果您想这样做,.Controls[1]将隐藏文本框部分。

整数和浮点数都需要被接受,包括负数。

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));
}

我已经为各种验证创建了一个可重用的文本框扩展类,并考虑将其共享。

您所需要做的就是抛出一个TextChange事件,然后调用Validate方法。它是这样的:

private void tbxAmount_TextChanged(object sender, EventArgs e)
{
tbxAmount.Validate(TextValidator.ValidationType.Amount);
}

下面是扩展类:

public static class TextValidator
{
public enum ValidationType
{
Amount,
Integer
}


/// <summary>
/// Validate a textbox on text change.
/// </summary>
/// <param name="tbx"></param>
/// <param name="validationType"></param>
public static void Validate(this TextBox tbx, ValidationType validationType)
{
PerformValidation(tbx, validationType);
tbx.Select(tbx.Text.Length, 0);
}




private static void PerformValidation(this TextBox tbx, ValidationType validationType)
{
char[] enteredString = tbx.Text.ToCharArray();
switch (validationType)
{
case ValidationType.Amount:
tbx.Text = AmountValidation(enteredString);
break;


case ValidationType.Integer:
tbx.Text = IntegerValidation(enteredString);
break;


default:
break;
}


tbx.SelectionStart = tbx.Text.Length;
}






private static string AmountValidation(char[] enteredString)
{
string actualString = string.Empty;
int count = 0;
foreach (char c in enteredString.AsEnumerable())
{
if (count >= 1 && c == '.')
{ actualString.Replace(c, ' '); actualString.Trim(); }
else
{
if (Char.IsDigit(c))
{
actualString = actualString + c;
}


if (c == '.')
{
actualString = actualString + c; count++;
}


else
{
actualString.Replace(c, ' ');
actualString.Trim();
}
}
}
return actualString;
}




private static string IntegerValidation(char[] enteredString)
{
string actualString = string.Empty;
foreach (char c in enteredString.AsEnumerable())
{
if (Char.IsDigit(c))
{
actualString = actualString + c;
}
else
{
actualString.Replace(c, ' ');
actualString.Trim();
}
}
return actualString;
}
}

你可以在这里找到完整的代码

这是我的方法:

  1. 使用linq(易于修改过滤器)
  2. 复制/粘贴证明代码
  3. 按下禁止字符时保持插入位置
  4. 接受左0
  5. 和任何大小的数字

    private void numeroCuenta_TextChanged(object sender, EventArgs e)
    {
    string org = numeroCuenta.Text;
    string formated = string.Concat(org.Where(c => (c >= '0' && c <= '9')));
    if (formated != org)
    {
    int s = numeroCuenta.SelectionStart;
    if (s > 0 && formated.Length > s && org[s - 1] != formated[s - 1]) s--;
    numeroCuenta.Text = formated;
    numeroCuenta.SelectionStart = s;
    }
    }
    

使用Fabio Iotti的回答中描述的方法,我创建了一个更通用的解决方案:

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"类继承,我们可以很容易地创建" positivevenumbertextbox "和"PositiveFloatingPointNumberTextBox"控件:

public sealed class PositiveNumberTextBox : RegexedTextBox {
public PositiveNumberTextBox() : base(@"^\d*$") { }
}


public sealed class PositiveFloatingPointNumberTextBox : RegexedTextBox {
public PositiveFloatingPointNumberTextBox()
: base(@"^(\d+\" + CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator + @")?\d*$") { }
}

WPF &工作解决方案;简单的TextChangedEventArgs

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var TextBox = (sender as TextBox);


// if not a numeric value, remove news characters
if (Regex.IsMatch(TextBox.Text, "[^0-9]"))
{
foreach (TextChange Change in e.Changes)
{
TextBox.Text = TextBox.Text.Remove(Change.Offset, Change.AddedLength);


TextBox.CaretIndex = Change.Offset;
}
}
}

通过这个简单的代码,您可以简单地防止添加非数值字符

 if (long.TryParse(TextBox.Text,out long isparsable))
{
// your code to handle numbers
}
else
{
TextBox.Text="Only Numbers Allowed";
TextBox.Focus();
TextBox.SelectAll();
}

使用正则表达式验证器:

<asp:TextBox ID="TextBoxNum" runat="server"></asp:TextBox><br />
<asp:RegularExpressionValidator ID="RegularExpressionValidator1"
ControlToValidate="TextBoxNum" runat="server"
ErrorMessage="Only numbers allowed"
ValidationExpression="\d+">
</asp:RegularExpressionValidator>

这里有30多个答案,很多答案都是有用的。但我想分享System.Windows.Forms.TextBoxSystem.Windows.Controls.TextBox的一般形式。

System.Windows.Controls.TextBox中没有<强>键盘按键< / >强事件。 这个答案是为那些想用相同逻辑实现System.Windows.Forms.TextBoxSystem.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;
}


}

# EYZ0代码:

public class PositiveNumberTextBox : NumberTextBox
{
public PositiveNumberTextBox()
{
SetProperties(0);
}
}

# EYZ0代码:

public class FractionNumberTextBox : NumberTextBox
{
public FractionNumberTextBox()
{
SetProperties(0, 0.999999);
}
}

最简单粗暴的方法是使用组合框而不是带有只读的文本框。当然,只有当你希望用户使用一个合理的整数集,而不是试图接近无穷大时,它才有用。

这是用.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 _);
}

编辑:增加了退格键的支持