我有一个windows窗体应用程序与一个文本框控件,我想只接受整数值。在过去,我通过重载KeyPress事件并删除不符合规范的字符来进行这种验证。我已经看了MaskedTextBox控件,但我想一个更通用的解决方案,可以与也许正则表达式,或依赖于其他控件的值。
理想情况下,按下非数字字符要么不产生结果,要么立即向用户提供关于无效字符的反馈。
我有一个windows窗体应用程序与一个文本框控件,我想只接受整数值。在过去,我通过重载KeyPress事件并删除不符合规范的字符来进行这种验证。我已经看了MaskedTextBox控件,但我想一个更通用的解决方案,可以与也许正则表达式,或依赖于其他控件的值。
理想情况下,按下非数字字符要么不产生结果,要么立即向用户提供关于无效字符的反馈。
当前回答
在我们的网页与文本框的定义,我们可以添加一个onkeypress事件只接受数字。它不会显示任何消息,但它将防止您输入错误。它为我工作,用户不能输入任何除了数字。
<asp:TextBox runat="server" ID="txtFrom"
onkeypress="if(isNaN(String.fromCharCode(event.keyCode))) return false;">
其他回答
你可以使用TextChanged/ Keypress事件,使用正则表达式过滤数字,并采取一些行动。
似乎目前对这个问题的许多答案都是手动解析输入文本。如果你正在寻找一个特定的内置数字类型(例如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;
}
}
}
整数和浮点数都需要被接受,包括负数。
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));
}
尝试一个MaskedTextBox。它采用一种简单的掩码格式,这样你就可以将输入限制为数字或日期之类的。
使用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*$") { }
}