21

如何在 Visual C# 文本框中只允许某些字符?用户应该能够在文本框中输入以下字符,并且应该阻止其他所有字符:0-9、+、-、/、*、(、)。

我用谷歌查找了这个问题,但我得到的唯一解决方案是只允许字母字符,只允许数字或不允许某些字符。我想要的不是禁止某些字符,我想默认禁止所有字符,除了我在代码中输入的字符。

4

6 回答 6

31

正如评论中提到的(以及我输入的另一个答案),您需要注册一个事件处理程序来捕获文本框上的 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;
    }
}
于 2012-09-26T17:32:15.093 回答
11

您需要订阅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意志。

于 2012-09-26T17:33:29.583 回答
1

您可能可以使用KeyDown 事件KeyPress 事件KeyUp 事件。我会首先尝试我认为的 KeyDown 事件。

您可以设置事件参数的 Handled 属性以停止处理事件。

于 2012-09-26T17:27:26.327 回答
1

在我看来,拦截 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;
}
于 2018-02-02T09:15:36.413 回答
0

对于您的验证事件 IMO,最简单的方法是使用字符数组来验证文本框字符。是的 - 迭代和验证并不是特别有效,但它很简单。

或者,对输入字符串使用白名单字符的正则表达式。您的活动在 MSDN 上可用:http: //msdn.microsoft.com/en-us/library/system.windows.forms.control.lostfocus.aspx

于 2012-09-26T17:31:28.020 回答
-1
    private void txtuser_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (!char.IsLetter(e.KeyChar) && !char.IsWhiteSpace(e.KeyChar) && !char.IsControl(e.KeyChar))
        {
            e.Handled = true;
        }
    }
于 2016-06-13T10:57:08.290 回答