Моя цель - реализовать пользовательский обработчик нажатия клавиш Control + S для подключения к пользовательскому методу сохранения в приложении winforms.
Есть несколько способов достичь этого, основанных на моих исследованиях и разработках. Во-первых, я попробовал очевидный обработчик события KeyPress. Он оказался недостаточно мощным, чтобы перехватить нужные мне нажатия клавиш (он не вызывался на уровне редактора, что мне и требовалось).
Второй вариант, который выглядит лучше, - это переопределение protected override bool ProcessCmdKey(ref Message msg, Keys keyData). Это работает - оно перехватывает нажатие клавиши CTRL, но, очевидно, мне нужно написать дополнительный код, чтобы сохранить факт нажатия клавиши CTRL и перехватить следующее нажатие клавиши (в моем случае это будет S), а затем выполнить пользовательское действие.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.S | Keys.Control))
{
// This is never called
}
else if (keyData == (Keys.Menu | Keys.Alt))
{
// this is called each time I hit CTRL
}
return true;
}
ProcessCmdKey, похоже, вызывается сразу после нажатия клавиши CTRL.
В этом сообщении предлагается создать класс KeyTracker, который будет сохранять нажатые клавиши и делать то, что ему нужно:
Capture Key Sequence via ProcessCmdKey
Это кажется хорошим вариантом, но прежде чем я начну копаться в реализации шаблона отслеживания памяти, есть ли у кого-нибудь идеи, как еще можно реализовать эту, казалось бы, обычную функцию?
Другой шаблон использует API-функцию GetKeyboardState:
Перехват нескольких нажатий клавиш в C#
Этот вариант кажется интересным, хотя я не уверен, что он подойдет для моих нужд.
[DllImport ("user32.dll")]
public static extern int GetKeyboardState( byte[] keystate );
private void Form1_KeyDown( object sender, KeyEventArgs e )
{
byte[] keys = new byte[255];
GetKeyboardState (keys);
if( keys[(int)Keys.Up] == 129 && keys[(int)Keys.Right] == 129 )
{
Console.WriteLine ("Up Arrow key and Right Arrow key down.");
}
}
Спасибо за внимание к моей проблеме.
UPDATE
Я добавил три события для обработки клавиш в DataPanel. Ни одно из этих событий не перехватывается VS, когда я устанавливаю точки останова в событиях, так что это то, что заставляет меня верить, что ProcessCmdKey - мой лучший вариант.
Если бы я мог заставить эти события работать, это было бы тоже хорошо:
// Ctrl + S: Save Support
this.ParentForm.KeyPreview = true;
this.KeyPress += new KeyPressEventHandler(DataPanel_KeyPress);
this.KeyDown += new KeyEventHandler(DataPanel_KeyDown);
this.PreviewKeyDown += new PreviewKeyDownEventHandler(DataPanel_PreviewKeyDown);
Ни одно из этих событий, похоже, не перехватывается при нажатии любых клавиш:
void DataPanel_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == (Keys.S | Keys.Control))
{
SessionManager.Trace.AddTrace("You Hit Save!!");
}
}
void DataPanel_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == (Keys.S | Keys.Control))
{
SessionManager.Trace.AddTrace("You Hit Save!!");
}
}
void DataPanel_KeyPress(object sender, KeyPressEventArgs e)
{
var key = e.KeyChar;
}
UPDATE
Я решил проблему, используя простое событие KeyUp и флаг KeyPreview:
void ShipmentDataPanel_KeyUp(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.S)
{
MessageBox.Show("Control + S Key Hit!");
}
}
Спасибо.