如何在 Visual C# 文本框中只允许某些字符?用户应该能够在文本框中输入以下字符,并且应该阻止其他所有字符:0-9、+、-、/、*、(、)。
我用谷歌查找了这个问题,但我得到的唯一解决方案是只允许字母字符,只允许数字或不允许某些字符。我想要的不是禁止某些字符,我想默认禁止所有字符,除了我在代码中输入的字符。
正如评论中提到的(以及我输入的另一个答案),您需要注册一个事件处理程序来捕获文本框上的 keydown 或 keypress 事件。这是因为 TextChanged 仅在 TextBox 失去焦点时触发
下面的正则表达式可让您匹配您想要允许的那些字符
Regex regex = new Regex(@"[0-9+\-\/\*\(\)]");
MatchCollection matches = regex.Matches(textValue);
而这恰恰相反并捕获了不允许的字符
Regex regex = new Regex(@"[^0-9^+^\-^\/^\*^\(^\)]");
MatchCollection matches = regex.Matches(textValue);
我不假设会有一个匹配,因为有人可以将文本粘贴到文本框中。在这种情况下捕获 textchanged
textBox1.TextChanged += new TextChangedEventHandler(textBox1_TextChanged);
private void textBox1_TextChanged(object sender, EventArgs e)
{
Regex regex = new Regex(@"[^0-9^+^\-^\/^\*^\(^\)]");
MatchCollection matches = regex.Matches(textBox1.Text);
if (matches.Count > 0) {
//tell the user
}
}
并验证单次按键
textBox1.KeyPress += new KeyPressEventHandler(textBox1_KeyPress);
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
// Check for a naughty character in the KeyDown event.
if (System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar.ToString(), @"[^0-9^+^\-^\/^\*^\(^\)]"))
{
// Stop the character from being entered into the control since it is illegal.
e.Handled = true;
}
}
您需要订阅KeyDown
文本框上的事件。然后是这样的:
private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (!char.IsControl(e.KeyChar)
&& !char.IsDigit(e.KeyChar)
&& e.KeyChar != '.' && e.KeyChar != '+' && e.KeyChar != '-'
&& e.KeyChar != '(' && e.KeyChar != ')' && e.KeyChar != '*'
&& e.KeyChar != '/')
{
e.Handled = true;
return;
}
e.Handled=false;
return;
}
要知道的重要一点是,如果您将Handled
属性更改为true
,它将不会处理击键。将其设置为false
意志。
您可能可以使用KeyDown 事件、KeyPress 事件或KeyUp 事件。我会首先尝试我认为的 KeyDown 事件。
您可以设置事件参数的 Handled 属性以停止处理事件。
在我看来,拦截 KeyPressed 事件是一个很好的可靠解决方案。如果您使用 RegExp,请注意触发代码字符(e.KeyChar 低于 32)。
但是,只要用户从剪贴板粘贴文本,这种方式仍然可以注入超出范围的字符。不幸的是,我没有找到正确的剪贴板事件来解决这个问题。
所以一个防水的解决方案是拦截TextBox.TextChanged。这里有时会在短时间内看到原始的超出范围的字符。我建议同时实施。
using System.Text.RegularExpressions;
private void Form1_Shown(object sender, EventArgs e)
{
filterTextBoxContent(textBox1);
}
string pattern = @"[^0-9^+^\-^/^*^(^)]";
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if(e.KeyChar >= 32 && Regex.Match(e.KeyChar.ToString(), pattern).Success) { e.Handled = true; }
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
filterTextBoxContent(textBox1);
}
private bool filterTextBoxContent(TextBox textBox)
{
string text = textBox.Text;
MatchCollection matches = Regex.Matches(text, pattern);
bool matched = false;
int selectionStart = textBox.SelectionStart;
int selectionLength = textBox.SelectionLength;
int leftShift = 0;
foreach (Match match in matches)
{
if (match.Success && match.Captures.Count > 0)
{
matched = true;
Capture capture = match.Captures[0];
int captureLength = capture.Length;
int captureStart = capture.Index - leftShift;
int captureEnd = captureStart + captureLength;
int selectionEnd = selectionStart + selectionLength;
text = text.Substring(0, captureStart) + text.Substring(captureEnd, text.Length - captureEnd);
textBox.Text = text;
int boundSelectionStart = selectionStart < captureStart ? -1 : (selectionStart < captureEnd ? 0 : 1);
int boundSelectionEnd = selectionEnd < captureStart ? -1 : (selectionEnd < captureEnd ? 0 : 1);
if (boundSelectionStart == -1)
{
if (boundSelectionEnd == 0)
{
selectionLength -= selectionEnd - captureStart;
}
else if (boundSelectionEnd == 1)
{
selectionLength -= captureLength;
}
}
else if (boundSelectionStart == 0)
{
if (boundSelectionEnd == 0)
{
selectionStart = captureStart;
selectionLength = 0;
}
else if (boundSelectionEnd == 1)
{
selectionStart = captureStart;
selectionLength -= captureEnd - selectionStart;
}
}
else if (boundSelectionStart == 1)
{
selectionStart -= captureLength;
}
leftShift++;
}
}
textBox.SelectionStart = selectionStart;
textBox.SelectionLength = selectionLength;
return matched;
}
对于您的验证事件 IMO,最简单的方法是使用字符数组来验证文本框字符。是的 - 迭代和验证并不是特别有效,但它很简单。
或者,对输入字符串使用白名单字符的正则表达式。您的活动在 MSDN 上可用:http: //msdn.microsoft.com/en-us/library/system.windows.forms.control.lostfocus.aspx
private void txtuser_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsLetter(e.KeyChar) && !char.IsWhiteSpace(e.KeyChar) && !char.IsControl(e.KeyChar))
{
e.Handled = true;
}
}