Winforms 当用户控件具有焦点时,如何触发窗体级事件?

Winforms 当用户控件具有焦点时,如何触发窗体级事件?,winforms,events,event-handling,user-controls,windows-forms-designer,Winforms,Events,Event Handling,User Controls,Windows Forms Designer,我有一个Windows窗体C#/.Net项目。有一个窗体上有多个用户控件。每个用户控件都是停靠的,因此它占据整个表单。单击一个用户控件上的按钮时,该用户控件将隐藏,并显示另一个用户控件。这是由同事完成的,正在生产中,无法更改(也就是说,我绝对无法摆脱用户控件,除非真的需要,否则无法更改它们)。我希望表单上有一个面板(或者另一个用户控件),可以在某个事件(比如按CTRL-Q之类的特定组合键)时打开。但是,如果我在表单上放置KeyDown事件,它永远不会被触发,因为其中一个用户控件始终具有焦点。我可

我有一个Windows窗体C#/.Net项目。有一个窗体上有多个用户控件。每个用户控件都是停靠的,因此它占据整个表单。单击一个用户控件上的按钮时,该用户控件将隐藏,并显示另一个用户控件。这是由同事完成的,正在生产中,无法更改(也就是说,我绝对无法摆脱用户控件,除非真的需要,否则无法更改它们)。我希望表单上有一个面板(或者另一个用户控件),可以在某个事件(比如按CTRL-Q之类的特定组合键)时打开。但是,如果我在表单上放置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
keydup
事件,请始终确保窗体上的属性
keydreview
设置为
TRUE

然后,该属性将确保窗体在控件之前首先获得击键

另见

编辑
另一种方法是停止为此使用
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;
}

重写表单的
ProcessCmdKey
。(即,
bool isControlQ=keyData==(Keys.Control | Keys.Q);)
。表单将在处理任何键之前处理任何键。谢谢。设置KeyPreview对我很有用。谢谢你的帮助!