繁体   English   中英

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

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

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

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

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

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

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

您可能忘记将表单的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);
}

在您的主表单上

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

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

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

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

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

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

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

在主表单中,您必须:

  • 确保将KeyPreview设置为true (默认为 TRUE)
  • 添加MainForm_KeyDown (..) - 通过它您可以在此处设置您想要的任何快捷方式。

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

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

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

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

您不需要欺骗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();
    }
}

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM