Разрешать только определенные символы в текстовом поле

Как я могу разрешить только определенные символы в текстовом поле Visual С#? Пользователи должны иметь возможность вводить следующие символы в текстовое поле, а все остальное должно быть заблокировано: 0-9, +, -,/, *, (,).

Я использовал Google для поиска этой проблемы, но единственные решения, которые я получаю, позволяют использовать только буквенные символы, только численные или запрещающие определенные символы. Я хочу не запрещать определенные символы, я хочу запретить все по умолчанию, кроме символов, которые я ввел в код.

Ответ 1

Как упоминалось в комментарии (и еще один ответ, когда я набирал), вам нужно зарегистрировать обработчик событий, чтобы поймать событие keydown или keypress в текстовом поле. Это связано с тем, что TextChanged запускается только тогда, когда TextBox теряет фокус

Ниже regex позволяет вам сопоставлять те символы, которые вы хотите разрешить

Regex regex = new Regex(@"[0-9+\-\/\*\(\)]");
MatchCollection matches = regex.Matches(textValue);

и это делает противоположное и ловит символы, которые не разрешены

Regex regex = new Regex(@"[^0-9^+^\-^\/^\*^\(^\)]");
MatchCollection matches = regex.Matches(textValue);

Я не предполагаю, что будет одно совпадение, так как кто-то может вставить текст в текстовое поле. в этом случае catch 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;
    }
}

Ответ 2

Вам нужно подписаться на событие 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 будет.

Ответ 3

Возможно, вы можете использовать событие KeyDown, событие KeyPress или событие KeyUp. Я бы сначала попробовал событие KeyDown, которое я думаю.

Вы можете установить свойство Handled событий args для прекращения обработки события.

Ответ 4

Для вашего события проверки IMO самым простым методом будет использование символьного массива для проверки символов в текстовом поле. Истина - итерация и проверка не являются особенно эффективными, но это просто.

В качестве альтернативы используйте регулярное выражение ваших символов белого списка в строке ввода. Ваши события доступны в MSDN здесь: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.lostfocus.aspx

Ответ 5

Перехват события KeyPressed - это, на мой взгляд, хорошее твердое решение. Обратите внимание на символы кода запуска (e.KeyChar ниже 32), если вы используете RegExp.

Но таким образом все еще можно вводить символы вне диапазона всякий раз, когда пользователь вставляет текст из буфера обмена. К сожалению, я не нашел правильных событий буфера обмена, чтобы исправить это.

Таким образом, водонепроницаемым решением является перехват 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;
}

Ответ 6

    private void txtuser_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (!char.IsLetter(e.KeyChar) && !char.IsWhiteSpace(e.KeyChar) && !char.IsControl(e.KeyChar))
        {
            e.Handled = true;
        }
    }