Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Windows窗体应用程序中实现键盘快捷键的最佳方法?_C#_Winforms_Keyboard Shortcuts - Fatal编程技术网

C# 在Windows窗体应用程序中实现键盘快捷键的最佳方法?

C# 在Windows窗体应用程序中实现键盘快捷键的最佳方法?,c#,winforms,keyboard-shortcuts,C#,Winforms,Keyboard Shortcuts,我正在寻找一种在我的C#应用程序中实现常用Windows键盘快捷键(例如Ctrl+F、Ctrl+N)的最佳方法 应用程序有一个主窗体,它承载许多子窗体(一次一个)。当用户点击Ctrl+F时,我想显示一个自定义搜索表单。搜索表单将取决于应用程序中当前打开的子表单 我想在ChildForm_KeyDown事件中使用类似的内容: 但这不起作用。当你按键时,事件甚至不会触发。解决方案是什么?最好的方法是使用菜单助记符,即在主窗体中设置菜单项,并为其分配所需的键盘快捷键。然后,所有其他操作都在内部处理,您

我正在寻找一种在我的C#应用程序中实现常用Windows键盘快捷键(例如Ctrl+F、Ctrl+N)的最佳方法

应用程序有一个主窗体,它承载许多子窗体(一次一个)。当用户点击Ctrl+F时,我想显示一个自定义搜索表单。搜索表单将取决于应用程序中当前打开的子表单

我想在ChildForm_KeyDown事件中使用类似的内容:


但这不起作用。当你按键时,事件甚至不会触发。解决方案是什么?

最好的方法是使用菜单助记符,即在主窗体中设置菜单项,并为其分配所需的键盘快捷键。然后,所有其他操作都在内部处理,您所要做的就是实现在该菜单项的
单击
事件处理程序中执行的相应操作。

您可能忘记了将表单的属性设置为True。覆盖该方法的是通用解决方案:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
  if (keyData == (Keys.Control | Keys.F)) {
    MessageBox.Show("What the Ctrl+F?");
    return true;
  }
  return base.ProcessCmdKey(ref msg, keyData);
}

如果您有一个菜单,那么更改
ToolStripMenuItem
ShortcutKeys
属性就可以了

如果没有,您可以创建一个,并在主窗体上将其
visible
属性设置为false。

  • KeyPreview
    设置为True
  • 使用以下代码添加KeyDown事件处理程序

    private void MainForm_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.N)
        {
            SearchForm searchForm = new SearchForm();
            searchForm.Show();
        }
    }
    
  • 对新手来说可能会更容易一些,所以这是我的版本

    您不需要愚弄
    KeyPreview
    ,将其设置为
    false
    。要使用下面的代码,只需将其粘贴到
    form1\u load
    下面,然后使用F5运行即可:

    protected override void OnKeyPress(KeyPressEventArgs ex)
    {
        string xo = ex.KeyChar.ToString();
    
        if (xo == "q") //You pressed "q" key on the keyboard
        {
            Form2 f2 = new Form2();
            f2.Show();
        }
    }
    

    您甚至可以尝试以下示例:

    public class MDIParent : System.Windows.Forms.Form
    {
        public bool NextTab()
        {
             // some code
        }
    
        public bool PreviousTab()
        {
             // some code
        }
    
        protected override bool ProcessCmdKey(ref Message message, Keys keys)
        {
            switch (keys)
            {
                case Keys.Control | Keys.Tab:
                  {
                    NextTab();
                    return true;
                  }
                case Keys.Control | Keys.Shift | Keys.Tab:
                  {
                    PreviousTab();
                    return true;
                  }
            }
            return base.ProcessCmdKey(ref message, keys);
        }
    }
    
    public class mySecondForm : System.Windows.Forms.Form
    {
        // some code...
    }
    

    在主窗体中,您必须:

    • 确保将KeyPreview设置为true(默认为true)
    • 添加MainForm\u向下键(..)-通过该键,您可以在此处设置所需的任何快捷方式
    另外,我在谷歌上找到了这个,我想把这个分享给那些仍在搜索答案的人。(适用于全球)

    我认为您必须使用user32.dll

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
    
        if (m.Msg == 0x0312)
        {
            /* Note that the three lines below are not needed if you only want to register one hotkey.
             * The below lines are useful in case you want to register multiple keys, which you can use a switch with the id as argument, or if you want to know which key/modifier was pressed for some particular reason. */
    
            Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);                  // The key of the hotkey that was pressed.
            KeyModifier modifier = (KeyModifier)((int)m.LParam & 0xFFFF);       // The modifier of the hotkey that was pressed.
            int id = m.WParam.ToInt32();                                        // The id of the hotkey that was pressed.
    
    
            MessageBox.Show("Hotkey has been pressed!");
            // do something
        }
    }
    

    在WinForm中进一步阅读此

    ,我们始终可以通过以下方式获取控制键状态:

    bool IsCtrlPressed = (Control.ModifierKeys & Keys.Control) != 0;
    

    问题是主窗体不使用常用的windows菜单。它使用用于显示子窗体的自定义导航面板。通过单击子窗体上的ToolStripButton可调用搜索窗体。
    菜单助记符
    real sample?@Kiquenet助记符与快捷键是一个不同的概念,它们的操作方式有重要区别。简而言之,助记符是带下划线的字符,用于使用键盘访问菜单、菜单命令和对话框控件。哦,快捷键是一种访问命令的方式,无需通过菜单,而且它们可以是任意的按键,如Ctrl+F或F5,而不限于字符键。@Stewart这是正确的!我的回答并不是要暗示所有的键盘快捷键都是助记符,只是菜单助记符是获得此功能的最简单方法。不幸的是,正如Rockcoder的评论所阐明的,这种解决方案在这里似乎并不合适。如果可能的话,我仍然推荐它作为更好的解决方案。一般来说,汉斯接受的答案是前进的方向。不,我没有菜单。用于搜索的ToolStripButton实际上位于BindingNavigator控件上,因此添加菜单可能不是一个选项。这很好,但仅在窗体是活动窗口时为我检测它。有人知道如何在任何窗口视图中绑定它吗?在某些情况下,
    KeyPreview
    是必不可少的。例如,当按下快捷键时,需要抑制输入,但允许触发单独的
    MenuStrip
    事件
    ProcessCmdKey
    方法将强制复制事件触发逻辑。嗯,不,表单的KeyDown事件处理程序与菜单项的Click事件处理程序完全不同。您仍然使用完全相同的方法,要么直接调用事件处理程序方法(不需要事件专门调用它),要么将公共逻辑重构为一个单独的方法。“Ctrl+F是什么?”LOL+for,将KeyPreview设置为True。。缺少这一点首先,重写ProcessCmdKey是处理用于执行类似命令的操作的击键的推荐方法,而OP正是询问这一点的。其次,您误解了Hans关于将KeyPreview设置为true的评论;他只是告诉OP为什么他的技术不起作用。使用ProcessCmdKey不需要将KeyPreview设置为true。Winforms似乎没有像本机Windows API那样的特定功能,这真是奇怪。
    bool IsCtrlPressed = (Control.ModifierKeys & Keys.Control) != 0;