У меня есть приложение winforms, которое содержит 3 элемента управления в моей форме: GroupBox gb1
который содержит ComboBox cmb1
и TextBox tb1
.Почему «ProcessCmdKey» дважды срабатывает для combobox, но один раз для текстового поля?
В Form1.cs
У меня есть следующий код:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (comboBox1.Focused)
MessageBox.Show("Cmb Focus");
else if (textBox1.Focused)
MessageBox.Show("Txtbox Focus");
return base.ProcessCmdKey(ref msg, keyData);
}
Если я остановлюсь мое текстовое поле и нажмите клавишу я получаю дисплей 1 MessageBox. Сфокусировано, я получаю 2 всплывающих окна.
Первоначально я наткнулся this question года полтора назад, и человек, который отвечал на вопрос, принял мое решение, которое просто цитирует MSDN:
Метод ProcessCmdKey первый определяет, имеет ли элемент управления в ContextMenu, и если это так, позволяет ContextMenu обрабатывать командный ключ. Если командный ключ не является ярлыком меню, а элемент управления имеет родителя, ключ передается методу ProcessCmdKey родителя. Чистый эффект заключается в том, что командные ключи «пузырятся» по иерархии управления.
Я понимаю, что он говорит, но в то же время я не понимаю «фактическое» поведение моего приложения.
Ни один элемент управления не имеет контекстного меню. Оба элемента управления имеют 1 родительский объект (поле группы). Так почему же они ведут себя по-другому?
Я попробовал несколько вещей, чтобы помочь мне понять:
1) Если я изменить код return true;
, оба элемента управления отображать только 1 окно сообщения. Если я изменю его на return false;
, я получаю такое же поведение, как описано ранее.
2) Я подумал, что, может быть, это был «побочный эффект» тот факт, что Combobox object наследует от System.Windows.Forms.ListControl
. Поэтому я попробовал просто добавить третий элемент управления, ListBox
, который также наследует от System.Windows.Forms.ListControl
. Но когда я фокусирую это ListBox
, я все еще получаю только 1 сообщение.
3) Я добавил к моему comboBox1.Items.Add("1");
Form1()
конструктора, а затем нажать клавишу на моей клавиатуре. Я подумал: «Может быть, если я нажму клавишу« соответствует »элементу коллекции Items
combobox, он отобразит только 1 всплывающее окно». Но нет, это все еще показывает дважды.
Это поведение было доведено до моего сведения вчера после того, как пользователь прокомментировал ответ, который я опубликовал в связанном выше вопросе, но я не смог найти , почему это происходит.
Что касается вашего последнего абзаца, я в основном просто удалял код в вопросе, который я связал, там оригинальный плакат вызывает метод 'base' в конце его' override'. Я не был уверен, было ли это «хорошей идеей», чтобы просто «вернуть истину», независимо от того, какой был вход, в случае, если это может изменить предполагаемое поведение элемента управления/приложения. – sab669
Вызов base.ProcessCmdKey() является сложным требованием или вы разрываете комбинацию клавиш в базовом классе. Но нет, если вы использовали нажатие клавиши, точка добавления 'return true;' –