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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
9 026
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

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

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

Ответ принят как подходящий

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

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

Вот как я обычно с этим справляюсь.

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

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

Эд: Я уже делаю это с помощью Regex, и мне нужно расширить текстовое поле, чтобы разрешить клавиши ctrl. Я обрабатываю Backspace и Delete как особые случаи в событии KeyPress, это событие KeyPress, в правильном месте выполняются ключевые проверки / блоки

benPearce 17.11.2008 05:06

Я обнаружил, что единственное рабочее решение закончилось предварительной проверкой нажатия клавиши в 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;
    }

}

Другие вопросы по теме