我有一个windows窗体应用程序与一个文本框控件,我想只接受整数值。在过去,我通过重载KeyPress事件并删除不符合规范的字符来进行这种验证。我已经看了MaskedTextBox控件,但我想一个更通用的解决方案,可以与也许正则表达式,或依赖于其他控件的值。
理想情况下,按下非数字字符要么不产生结果,要么立即向用户提供关于无效字符的反馈。
我有一个windows窗体应用程序与一个文本框控件,我想只接受整数值。在过去,我通过重载KeyPress事件并删除不符合规范的字符来进行这种验证。我已经看了MaskedTextBox控件,但我想一个更通用的解决方案,可以与也许正则表达式,或依赖于其他控件的值。
理想情况下,按下非数字字符要么不产生结果,要么立即向用户提供关于无效字符的反馈。
当前回答
这正是设计已验证/正在验证事件的目的。
下面是MSDN上关于这个主题的文章:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validating.aspx
TL;DR版本:检查validate事件中的. text属性,并在数据无效时设置e.Cancel=True。
当你设置e.Cancel=True时,用户不能离开这个字段,但是你需要给他们一些错误的反馈。我将方框的背景颜色更改为浅红色,以表示有问题。确保将其设置回SystemColors。窗口时调用一个良好的值。
其他回答
看一下WinForm中的输入处理
我已经发布了我的解决方案,在文本框上使用ProcessCmdKey和OnKeyPress事件。注释向您展示了如何使用Regex来验证键按和适当地阻止/允许。
只是因为在一条线上做事情总是更有趣……
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
}
注意:这并不阻止用户复制/粘贴到此文本框。这并不是清除数据的安全方法。
似乎目前对这个问题的许多答案都是手动解析输入文本。如果你正在寻找一个特定的内置数字类型(例如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 xmm_textbox_KeyPress(object sender, KeyPressEventArgs e) {
double x;
e.Handled = !double.TryParse(((TextBox)sender).Text, out x);
}
我从上下文和您使用的标记假设您正在编写一个。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);
}
}