我有一个winforms应用程序,其中包含3个控件:GroupBox gb1
,其中包含ComboBox cmb1
和TextBox tb1
。
在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);
}
如果我关注文本框并按一个键,我会看到一个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()
构造函数中,然后按下键盘上的 1 键。我想,“也许如果我按下一个键'对应'组合框的Items
集合中的一个项目,它只会显示1个弹出窗口。”但不,它仍然显示两次。
在用户评论我在上面链接的问题中发布的答案后,昨天引起了我的注意,但是我无法弄清楚为什么会发生这种情况。
答案 0 :(得分:2)
这有点怪癖,特别是ComboBox。它的消息处理程序中有calls ProcessCmdKey as well。不是100%肯定它为什么这样做,但几乎肯定与下拉菜单而不是文本框收到的击键有关。
除了本机组合框处理消息的方式的副作用之外,如果它们不用于选择下拉列表中的项目,它会将WM_KEYDOWN消息从下拉列表转发到文本框。在"默认组合框行为"中描述the SDK doc page的部分。并且没有办法告诉它来自何处,因此Winforms无法使其具有选择性。
是的,当你处理击键时,你肯定应该return true;
,总是必要的。我不能告诉你为什么跳过这个但它确实解决了这个问题。也许IMessageFilter可以解决您的问题(没有尝试过),但问题并没有给出任何暗示真实问题的暗示。