Лучший способ реализовать сочетания клавиш в приложении Windows Forms? - PullRequest
265 голосов
/ 30 декабря 2008

Я ищу лучший способ реализовать обычные сочетания клавиш Windows (например, Ctrl + F , Ctrl + N ) в моем приложении Windows Forms в C #.

Приложение имеет основную форму, которая содержит множество дочерних форм (по одной за раз). Когда пользователь нажимает Ctrl + F , я хотел бы показать форму пользовательского поиска. Форма поиска будет зависеть от текущей открытой дочерней формы в приложении.

Я думал об использовании чего-то подобного в ChildForm_KeyDown событии:

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

Но это не работает. Событие даже не срабатывает, когда вы нажимаете клавишу. Какое решение?

Ответы [ 11 ]

439 голосов
/ 30 декабря 2008

Возможно, вы забыли установить для свойства 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);
}
68 голосов
/ 04 августа 2011

В вашей основной форме

  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();
        }
    }
    
19 голосов
/ 30 декабря 2008

Лучший способ - использовать мнемонику меню, т. Е. Иметь пункты меню в основной форме, которым назначены нужные сочетания клавиш. Затем все остальное обрабатывается внутренне, и все, что вам нужно сделать, это реализовать соответствующее действие, которое выполняется в обработчике события Click этого пункта меню.

11 голосов
/ 11 мая 2012

Вы даже можете попробовать этот пример:

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...
}
8 голосов
/ 30 декабря 2008

Если у вас есть меню, тогда изменение ShortcutKeys свойства ToolStripMenuItem должно помочь.

Если нет, вы можете создать его и установить для его свойства visible значение false.

4 голосов
/ 16 ноября 2015

Из основной формы вы должны:

  • Убедитесь, что вы установили KeyPreview в true (по умолчанию TRUE)
  • Добавить MainForm_KeyDown (..) - с помощью которого вы можете установить здесь любые нужные вам ярлыки.

Кроме того, я нашел это в Google и хотел бы поделиться этим с теми, кто все еще ищет ответы. (для глобального)

Я думаю, вы должны использовать 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/

4 голосов
/ 09 сентября 2011

Ответ Ганса может быть немного проще для новичка в этом, так что вот моя версия.

Вам не нужно дурачиться с 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();
    }
}
1 голос
/ 31 декабря 2016

В WinForm мы всегда можем получить статус управляющего ключа:

bool IsCtrlPressed = (Control.ModifierKeys & Keys.Control) != 0;
0 голосов
/ 10 января 2018
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;
        }
    }
}
0 голосов
/ 10 января 2018
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;
}
...