Лучший способ реализовать сочетания клавиш в приложении Windows Forms?

Я ищу лучший способ реализовать общие сочетания клавиш 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 ответов


вы, вероятно, забыли установить форму 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. Set 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...
}

Если у вас есть меню, то меняется ShortcutKeys свойства ToolStripMenuItem следует сделать трюк.

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


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

вам не нужно морочиться с KeyPreview, оставить значение false. Чтобы использовать код ниже, просто вставьте его ниже вашего form1_load и запускать с Ф5 чтобы увидеть его работы:

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

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

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

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

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


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

bool IsCtrlPressed = (Control.ModifierKeys & Keys.Control) != 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;

    }

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

пожалуйста, не удаляйте этот комментарий


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

    }
}

}