当用户控件获得焦点时,如何触发表单级事件?
How do I trigger a form level event when a user control has the focus?
我有一个 Windows Form C#/.Net 项目。有一个带有多个用户控件的表单。每个用户控件都停靠在整个窗体中。单击一个用户控件上的按钮时,会隐藏该用户控件并显示另一个用户控件。这是由一位同事完成的,并且正在生产中,无法更改(也就是说,我绝对不能摆脱用户控件,除非真的有必要,否则不能更改它们)。我想要窗体上的一个面板(或者可能是另一个用户控件),可以在某些事件(比如按下某个组合键,如 CTRL-Q)时出现。但是,如果我在窗体上放置一个 KeyDown 事件,它永远不会被触发,因为其中一个用户控件始终具有焦点。我可以将我的新面板放在每个用户控件上,并在每个用户控件上都有 KeyDown 事件,但我真的不应该更改现有的用户控件,我真的不想要这个面板的多个实例和多个事件。当其中一个用户控件获得焦点时,如何触发表单级事件?
窗体、用户控件和面板的布局如下。用户控件实际上停靠以填充整个表单;我在这张插图中将它们交错排列,以便您可以看到它们。
----------------------------------------------------------------------
| form1 |
| |
| --------------------------------------------------------------- |
| | userControl1 | |
| | | |
| | | |
| | -------------------------------------------------------- | |
| | | userControl2 | | |
| | | | | |
| | | | | |
| | | -------------------------------------------------- | | |
| | | | userControl3 | | | |
| | | | | | | |
| | | --------------------------------------------------- | | |
| | | | | |
| | -------------------------------------------------------- | |
| | | |
| --------------------------------------------------------------- |
| |
| |
| ------------------------------------------------------------------ |
| | panel or user control on top of everything, visible on demand | |
| ------------------------------------------------------------------ |
| |
----------------------------------------------------------------------
我想要的是无论用户控件处于活动状态如何都触发来自 form1 的事件:
private void form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.Q)
{
panel1.Visible = true;
}
}
如果您想在表单上使用 KeyDown
或 KeyUp
事件,请始终确保将表单上的 属性 KeyPreview
设置为 TRUE
然后 属性 将确保表单首先获得击键,然后控件才获得击键
另见 this
编辑
另一种方法是停止为此使用 KeyDown/KeyUp
事件,并覆盖表单上的 ProcessCmdKey,正如@Jimi 在他的评论
中建议的那样
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
bool Result = true;
if (keyData == Keys.Control | Keys.Q)
{
panel1.Visible = true;
}
else
{
Result = base.ProcessCmdKey(ref msg, keyData);
}
return Result;
}
我有一个 Windows Form C#/.Net 项目。有一个带有多个用户控件的表单。每个用户控件都停靠在整个窗体中。单击一个用户控件上的按钮时,会隐藏该用户控件并显示另一个用户控件。这是由一位同事完成的,并且正在生产中,无法更改(也就是说,我绝对不能摆脱用户控件,除非真的有必要,否则不能更改它们)。我想要窗体上的一个面板(或者可能是另一个用户控件),可以在某些事件(比如按下某个组合键,如 CTRL-Q)时出现。但是,如果我在窗体上放置一个 KeyDown 事件,它永远不会被触发,因为其中一个用户控件始终具有焦点。我可以将我的新面板放在每个用户控件上,并在每个用户控件上都有 KeyDown 事件,但我真的不应该更改现有的用户控件,我真的不想要这个面板的多个实例和多个事件。当其中一个用户控件获得焦点时,如何触发表单级事件?
窗体、用户控件和面板的布局如下。用户控件实际上停靠以填充整个表单;我在这张插图中将它们交错排列,以便您可以看到它们。
----------------------------------------------------------------------
| form1 |
| |
| --------------------------------------------------------------- |
| | userControl1 | |
| | | |
| | | |
| | -------------------------------------------------------- | |
| | | userControl2 | | |
| | | | | |
| | | | | |
| | | -------------------------------------------------- | | |
| | | | userControl3 | | | |
| | | | | | | |
| | | --------------------------------------------------- | | |
| | | | | |
| | -------------------------------------------------------- | |
| | | |
| --------------------------------------------------------------- |
| |
| |
| ------------------------------------------------------------------ |
| | panel or user control on top of everything, visible on demand | |
| ------------------------------------------------------------------ |
| |
----------------------------------------------------------------------
我想要的是无论用户控件处于活动状态如何都触发来自 form1 的事件:
private void form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.Q)
{
panel1.Visible = true;
}
}
如果您想在表单上使用 KeyDown
或 KeyUp
事件,请始终确保将表单上的 属性 KeyPreview
设置为 TRUE
然后 属性 将确保表单首先获得击键,然后控件才获得击键
另见 this
编辑
另一种方法是停止为此使用 KeyDown/KeyUp
事件,并覆盖表单上的 ProcessCmdKey,正如@Jimi 在他的评论
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
bool Result = true;
if (keyData == Keys.Control | Keys.Q)
{
panel1.Visible = true;
}
else
{
Result = base.ProcessCmdKey(ref msg, keyData);
}
return Result;
}