Обработка ввода в WinForm

Каков наилучший способ блокировать использование определенных клавиш ввода в TextBox без блокировки специальных нажатий клавиш, таких как Ctrl-V/Ctrl-C?

Например, только разрешая пользователю вводить подмножество символов или цифр, таких как A или B или C, и ничего больше.

Ответ 1

Я бы использовал событие keydown и использовал e.cancel, чтобы остановить ключ, если ключ не разрешен. Если я хочу сделать это на нескольких местах, я бы сделал пользовательский элемент управления, который наследует текстовое поле, а затем добавит свойство AllowedChars или DisallowedChars, которые обрабатывают его для меня. У меня есть несколько вариантов, которые я использую время от времени, некоторые из них позволяют форматирование и ввод денег, некоторые для редактирования времени и так далее.

Хорошей вещью сделать это как пользовательский элемент управления является то, что вы можете добавить к нему и сделать его в свой собственный killer-text-box.;)

Ответ 2

Я использовал Masked Textbox для winforms. Там более длинное объяснение здесь. По сути, он запрещает ввод, который не соответствует критериям для поля. Если вы не хотите, чтобы люди вводили ничего, кроме цифр, это просто не позволяло им вводить ничего, кроме цифр.

Ответ 3

Вот как я обычно это делаю.

Regex regex = new Regex("[0-9]|\b");            
e.Handled = !(regex.IsMatch(e.KeyChar.ToString()));

Это позволит только числовые символы и обратное пространство. Проблема в том, что в этом случае вам не будет разрешено использовать клавиши управления. Я бы создал свой собственный класс текстового поля, если вы хотите сохранить эту функциональность.

Ответ 4

Я обнаружил, что единственное работающее решение, закончившееся тем, что делает предварительную проверку нажатия клавиш в ProcessCmdKey для Ctrl-V, Ctrl-C, Delete или Backspace и делает дополнительную проверку, если это не один из этих ключей в событие KeyPress, используя регулярное выражение.

Это, вероятно, не самый лучший способ, но он работал в моих обстоятельствах.

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    // check the key to see if it should be handled in the OnKeyPress method
    // the reasons for doing this check here is:
    // 1. The KeyDown event sees certain keypresses differently, e.g NumKeypad 1 is seen as a lowercase A
    // 2. The KeyPress event cannot see Modifer keys so cannot see Ctrl-C,Ctrl-V etc.
    // The functionality of the ProcessCmdKey has not changed, it is simply doing a precheck before the 
    // KeyPress event runs
    switch (keyData)
    {
        case Keys.V | Keys.Control :
        case Keys.C | Keys.Control :
        case Keys.X | Keys.Control :
        case Keys.Back :
        case Keys.Delete :
            this._handleKey = true;
            break;
        default:
            this._handleKey = false;
            break;
    }
    return base.ProcessCmdKey(ref msg, keyData);
}


protected override void OnKeyPress(KeyPressEventArgs e)
{
    if (String.IsNullOrEmpty(this._ValidCharExpression))
    {
        this._handleKey = true;
    }
    else if (!this._handleKey)
    {
        // this is the final check to see if the key should be handled
        // checks the key code against a validation expression and handles the key if it matches
        // the expression should be in the form of a Regular Expression character class
        // e.g. [0-9\.\-] would allow decimal numbers and negative, this does not enforce order, just a set of valid characters
        // [A-Za-z0-9\-_\@\.] would be all the valid characters for an email
        this._handleKey = Regex.Match(e.KeyChar.ToString(), this._ValidCharExpression).Success;
    }
    if (this._handleKey)
    {
        base.OnKeyPress(e);
        this._handleKey = false;
    }
    else
    {
        e.Handled = true;
    }

}

Ответ 5

Вы можете использовать событие TextChanged для текстового поля.

    private void txtInput_TextChanged(object sender, EventArgs e)
    {
        if (txtInput.Text.ToUpper() == "A" || txtInput.Text.ToUpper() == "B")
        {
            //invalid entry logic here
        }
    }