My goal is to implement a custom Control + S key press handler to wire up to a custom save method in a winforms app.
There are several ways to accomplish this based on my R&D. First, I tried the obvious KeyPress event handler. This wasn't powerful enough to capture the key presses I need (it wasn't called on the Editor level, which is what I needed).
The second option which looks better is the protected override bool ProcessCmdKey(ref Message msg, Keys keyData) override. This works - it intercepts the CTRL key click, but apparently I need to write extra code to persist the fact the CTRL key is pressed and intercept the next key press (which would be S in my case) and then perform the custom action.
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 seems to be called immediately after I hit the CTRL key.
This post suggests creating a KeyTracker class that will persist the keys pressed and do what it needs to do:
Capture Key Sequence via ProcessCmdKey
Which seems like a good option, but before I dig in an implement a memento tracking pattern, does anyone have input on how else to accomplish this seemingly common feature?
Another pattern uses the GetKeyboardState API function:
Capture multiple key downs in C#
This seems interesting, though I'm not sure it will suite my needs.
[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.");
}
}
Thank you for taking a look at my problem.
UPDATE
I've added three events for key handling to my DataPanel. None of these events are being picked up by VS when I set breakpoints in the events, so this is what leads me to believe that ProcessCmdKey is my best option.
If I could get these Events to work, that would be good as well:
// 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);
None of these events seem to be caught when pressing any keys:
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
I've solved the problem by using a simple KeyUp event and the KeyPreview flag:
void ShipmentDataPanel_KeyUp(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.S)
{
MessageBox.Show("Control + S Key Hit!");
}
}
Thank you.
Set the KeyPreview
property of our form to true
. The summary of this property says: "Gets or sets a value indicating whether the form will receive key events before the event is passed to the control that has focus.". Then use the KeyUp
event. Unless KeyPressed
it gives also information on special keys like control keys.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With