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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/400113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 01:58:42  来源:igfitidea点击:

Best way to implement keyboard shortcuts in a Windows Forms application?

c#winformskeyboard-shortcuts

提问by Rockcoder

I'm looking for a best way to implement common Windows keyboard shortcuts (for example Ctrl+F, Ctrl+N) in my Windows Formsapplication in C#.

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

The application has a main form which hosts many child forms (one at a time). When a user hits Ctrl+F, I'd like to show a custom search form. The search form would depend on the current open child form in the application.

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

I was thinking of using something like this in the ChildForm_KeyDownevent:

我想在ChildForm_KeyDown事件中使用这样的东西:

   if (e.KeyCode == Keys.F && Control.ModifierKeys == Keys.Control)
        // Show search form

But this doesn't work. The event doesn't even fire when you press a key. What is the solution?

但这不起作用。当您按下某个键时,该事件甚至不会触发。解决办法是什么?

采纳答案by Hans Passant

You probably forgot to set the form's KeyPreviewproperty to True. Overriding the ProcessCmdKey()method is the generic solution:

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

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);
}

回答by Konrad Rudolph

The best way is to use menu mnemonics, i.e. to have menu entries in your main form that get assigned the keyboard shortcut you want. Then everything else is handled internally and all you have to do is to implement the appropriate action that gets executed in the Clickevent handler of that menu entry.

最好的方法是使用菜单助记符,即在您的主窗体中有菜单条目,这些条目被分配了您想要的键盘快捷键。然后其他一切都在内部处理,您所要做的就是实现在Click该菜单项的事件处理程序中执行的适当操作。

回答by Corin Blaikie

If you have a menu then changing ShortcutKeysproperty of the ToolStripMenuItemshould do the trick.

如果您有菜单,那么更改 的ShortcutKeys属性ToolStripMenuItem应该可以解决问题。

If not, you could create one and set its visibleproperty to false.

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

回答by Almir

On your Main form

在您的主表单上

  1. Set KeyPreviewto True
  2. Add KeyDown event handler with the following code

    private void MainForm_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.N)
        {
            SearchForm searchForm = new SearchForm();
            searchForm.Show();
        }
    }
    
  1. 设置KeyPreview为真
  2. 使用以下代码添加 KeyDown 事件处理程序

    private void MainForm_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.N)
        {
            SearchForm searchForm = new SearchForm();
            searchForm.Show();
        }
    }
    

回答by Abhishek Jha

Hans's answercould be made a little easier for someone new to this, so here is my version.

对于刚接触这个的人来说,汉斯的回答可能会更容易一些,所以这是我的版本。

You do not need to fool with KeyPreview, leave it set to false. To use the code below, just paste it below your form1_loadand run with F5to see it work:

你不需要愚弄KeyPreview,让它设置为false。要使用下面的代码,只需将其粘贴在您的下方form1_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();
    }
}

回答by Shilpa

You can even try this example:

你甚至可以试试这个例子:

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...
}

回答by Juran

From the main Form, you have to:

在主表单中,您必须:

  • Be sure you set KeyPreviewto true( TRUE by default)
  • Add MainForm_KeyDown(..) - by which you can set here any shortcuts you want.
  • 确保将KeyPreview设置为true(默认为TRUE)
  • 添加MainForm_KeyDown(..) - 通过它您可以在此处设置您想要的任何快捷方式。

Additionally,I have found this on google and I wanted to share this to those who are still searching for answers. (for global)

此外,我在谷歌上找到了这个,我想分享给那些仍在寻找答案的人。(全球)

I think you have to be using user32.dll

我认为你必须使用 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
    }
}

Further read this http://www.fluxbytes.com/csharp/how-to-register-a-global-hotkey-for-your-application-in-c/

进一步阅读此http://www.fluxbytes.com/csharp/how-to-register-a-global-hotkey-for-your-application-in-c/

回答by s k

In WinForm, we can always get the Control Key status by:

在 WinForm 中,我们始终可以通过以下方式获取 Control Key 状态:

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