Обработка ввода в WinForm
-
08-07-2019 - |
Вопрос
Каков наилучший способ заблокировать использование определенных клавиш ввода в TextBox без блокирования специальных нажатий клавиш, таких как Ctrl-V / Ctrl-C?
Например, разрешить пользователю только вводить подмножество символов или цифр, таких как A или B или C, и ничего больше. Р>
Решение
Я бы использовал keydown-событие и использовал e.cancel, чтобы остановить ключ, если ключ не разрешен. Если я хочу сделать это в нескольких местах, я бы создал пользовательский элемент управления, который наследует текстовое поле, а затем добавил бы свойство AllowedChars или DisallowedChars, которое обрабатывает его для меня. У меня есть несколько вариантов, которые я использую время от времени, некоторые позволяют форматирование денег и ввод, некоторые для редактирования времени и так далее. Р>
Хорошая вещь, чтобы сделать это как пользовательский элемент управления, состоит в том, что вы можете добавить к нему и сделать это в своем собственном текстовом поле убийцы. ;) Р>
Другие советы
Я использовал элемент управления Masked Textbox для маскировки. Более подробное объяснение этого можно найти здесь . По сути, он запрещает ввод, который не соответствует критериям для поля. Если вы не хотите, чтобы люди вводили что-либо, кроме цифр, это просто не позволяло бы им вводить что-либо, кроме цифр. Р>
Вот как я обычно это делаю. Р>
Regex regex = new Regex("[0-9]|\b");
e.Handled = !(regex.IsMatch(e.KeyChar.ToString()));
Это позволит использовать только цифровые символы и пробел. Проблема в том, что вам не разрешат использовать клавиши управления в этом случае. Я бы создал свой собственный класс текстового поля, если вы хотите сохранить эту функциональность.
Я обнаружил, что единственное работающее решение закончилось выполнением предварительной проверки нажатия клавиши в 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;
}
}
Вы можете использовать событие TextChanged для текстового поля.
private void txtInput_TextChanged(object sender, EventArgs e)
{
if (txtInput.Text.ToUpper() == "A" || txtInput.Text.ToUpper() == "B")
{
//invalid entry logic here
}
}