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

时间:2008-12-30 12:03:07

标签: c# winforms keyboard-shortcuts

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

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

我想在 ChildForm_KeyDown 事件中使用类似的东西:

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

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

11 个答案:

答案 0 :(得分:437)

您可能忘记将表单的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 :(得分:68)

在主表单上

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

答案 2 :(得分:19)

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

答案 3 :(得分:11)

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

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

答案 4 :(得分:8)

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

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

答案 5 :(得分:4)

对于刚来这个的人来说,{p> Hans's answer可以变得更容易了,所以这是我的版本。

您无需愚弄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();
    }
}

答案 6 :(得分:4)

从主表单中,您必须:

  • 请务必将 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/

答案 7 :(得分:1)

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

{{1}}

答案 8 :(得分:0)

private void buttonCheck_Click_1(object sender, EventArgs e)
{
    bool jeElement = false;

    for (int i = 0; i < listBox1.Items.Count; i++)
    {
        if (textBox1.Text == listBox1.Items[i].ToString())
        {
            jeElement = true;
            break;
        }
    }

    if (jeElement)
    {
        label1.Text = "je element";
    }
    else
    {
        label1.Text = "ni element";
    }
    textBox1.ResetText();
    textBox1.Focus();
}

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Alt == true && e.KeyCode == Keys.A)
    {
        buttonCheck.PerformClick();
    }
}
private void timer1_Tick(object sender, EventArgs e)
{
    if (radioButtonF.Checked)
    {
        progressBar1.Value++;
    }
    else
    {
        progressBar1.Value--;
    }

    if (progressBar1.Value == progressBar1.Maximum)
    {
        timer1.Stop();
        label1.Text = "End";
    }

    if (progressBar1.Value == progressBar1.Minimum)
    {
        timer1.Stop();
        label1.Text = "Begining";
    }
}

private void radioButtonF_CheckedChanged(object sender, EventArgs e)
{
    timer1.Start();
    progressBar1.Value = 0;
    progressBar1.Maximum = 100;
}

private void radioButtonB_CheckedChanged(object sender, EventArgs e)
{
    timer1.Start();
    progressBar1.Value = 100;
    progressBar1.Minimum = 0;
}

请不要删除此评论

答案 9 :(得分:0)

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if(e.Alt == true && e.KeyCode == Keys.A)
    {
        button1ADD.PerformClick();
    }

    if(e.Alt == true && e.KeyCode == Keys.D)
    {
        button2DeleteaaLL.PerformClick();
    }

    if(e.Alt == true && e.KeyCode == Keys.S)
    {
        Deleteselectedbtn.PerformClick();
    }

    if(e.Alt == true && e.KeyCode == Keys.C)
    {
        button4Close.PerformClick();
    }
}

private void Form1_Shown(object sender, EventArgs e)
{
    txtInput.Focus();
}

private void button1ADD_Click(object sender, EventArgs e)
{
    if(!string.IsNullOrEmpty(txtInput.Text))
    {
        Listmylist.Items.Add(txtInput.Text);
        txtInput.Clear();
        txtInput.Focus();
    }
}

private void button2DeleteaaLL_Click(object sender, EventArgs e)
{
    Listmylist.Items.Clear();
    txtInput.Focus();
}

private void Deleteselectedbtn_Click(object sender, EventArgs e)
{
    Listmylist.Items.RemoveAt(Listmylist.SelectedIndex);
    txtInput.Focus();
}

private void button4Close_Click(object sender, EventArgs e)
{
    Application.Exit();
}

private void txtInput_TextChanged(object sender, EventArgs e)
{
    button1ADD.Enabled = true;
}

答案 10 :(得分:-1)

private void button1_Click(object sender, EventArgs e)
{
    if (button2.Enabled == false)
    {
        timer1.Stop();
        button2.Enabled = true;
        label1.Text = "Preteklo je " + progressBar1.Value + " desetink";

    }
    else
    {
        timer1.Start();
        button1.Enabled = false;
        progressBar1.Value = 0;
        label1.Text = "";
    }
}

private void button2_Click(object sender, EventArgs e)
{
    if (button1.Enabled == false)
    {
        timer1.Stop();
        button1.Enabled = true;
        label1.Text = "Preteklo je " + progressBar1.Value + " desetink";
    }
    else
    {
        timer1.Start();
        button2.Enabled = false;
        progressBar1.Value = 0;
        label1.Text = "";
    }
}

private void timer1_Tick(object sender, EventArgs e)
{
    if (progressBar1.Value < progressBar1.Maximum)
    {
        progressBar1.Value++;
        if (progressBar1.Value == progressBar1.Maximum)
        {
            timer1.Stop();
            button2.Enabled = true;
            button1.Enabled = true;
        }
    }
}