Лучший способ реализовать сочетания клавиш в приложении Windows Forms?
Я ищу лучший способ реализовать обычные сочетания клавиш Windows (например Ctrl + F, Ctrl + N) в Windows Forms на С#.
Приложение имеет основную форму, в которой размещается множество дочерних форм (по одному за раз). Когда пользователь нажимает Ctrl + F, я хотел бы показать специальную форму поиска. Форма поиска будет зависеть от текущей открытой дочерней формы в приложении.
Я думал об использовании чего-то подобного в событии ChildForm_KeyDown:
if (e.KeyCode == Keys.F && Control.ModifierKeys == Keys.Control)
// Show search form
Но это не работает. Событие даже не срабатывает, когда вы нажимаете клавишу. Каково решение?
Ответы
Ответ 1
Вероятно, вы забыли установить для свойства 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);
}
Ответ 2
В вашей основной форме
- Установите
KeyPreview
в True
-
Добавить обработчик событий KeyDown со следующим кодом
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.N)
{
SearchForm searchForm = new SearchForm();
searchForm.Show();
}
}
Ответ 3
Лучший способ - использовать мнемонику меню, т.е. иметь записи меню в вашей основной форме, которые получают назначенный вам ярлык клавиатуры. Затем все остальное обрабатывается внутренне, и все, что вам нужно сделать, - выполнить соответствующее действие, которое выполняется в обработчике событий Click
этого элемента меню.
Ответ 4
Вы даже можете попробовать этот пример:
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...
}
Ответ 5
Если у вас есть меню, то изменение ShortcutKeys
свойства ToolStripMenuItem
должно выполнить трюк.
Если нет, вы можете создать его и установить для свойства visible
значение false.
Ответ 6
Ответ Hans может быть немного легче для кого-то нового для этого, так что вот моя версия.
Вам не нужно обманывать 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();
}
}
Ответ 7
Из основной формы вы должны:
- Обязательно установите 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/
Ответ 8
В WinForm мы всегда можем получить статус Control Key:
bool IsCtrlPressed = (Control.ModifierKeys & Keys.Control) != 0;
Ответ 9
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;
}
пожалуйста, не удаляйте этот комментарий
Ответ 10
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;
}
Ответ 11
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;
}
}
}