How to use multiple modifier keys in C# - c#

I am using a keydown event to detect keys pressed and have several key combinations for various operations.
if (e.KeyCode == Keys.C && e.Modifiers == Keys.Control && e.Modifiers == Keys.Shift)
{
//Do work
}
else if (e.KeyCode == Keys.V && e.Modifiers == Keys.Control)
{
//Paste
}
For some reason the key combination in which I hit Ctrl + Shift + C is not working. I have re ordered them, and placed it at the top thinking it might be interference from the Ctrl + C, and even removed the Ctrl + C to see if it was causing a problem. It still does not work. I know it's probably something very simple, but can't quite grasp what it is. All of my 1 modifier + 1 key combination's work fine, as soon as I add a second modifier is when it no longer works.

if (e.KeyCode == Keys.C && e.Modifiers == (Keys.Control | Keys.Shift))
{
//Do work
}
else if (e.KeyCode == Keys.V && e.Modifiers == Keys.Control)
{
//Paste
}

Have you tried e.Modifiers == (Keys.Control | Keys.Shift)?

If you want to allow Ctrl and Shift then use the bitwise OR (as Keys is a Flags enum)
if (e.KeyCode == Keys.C && e.Modifiers == (Keys.Control | Keys.Shift))
{
//Do work (if Ctrl-Shift-C is pressed, but not if Alt is pressed as well)
}
else if (e.KeyCode == Keys.V && e.Modifiers == Keys.Control)
{
//Paste (if Ctrl is only modifier pressed)
}
This will fail if Alt is pressed as well

Another way would be to add an invisible menu item, assign the Ctrl + Shift + C shortcut to it, and handle the event there.

if ((Keyboard.Modifiers & ModifierKeys.Shift | ModifierKeys.Control) > 0)
Debugger.Launch();

This is what I did for a Ctrl+Z Undo and Ctrl+Shift+Z Redo operation and it worked.
Private Sub Form_Main_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
Select Case e.KeyCode
Case Keys.Add
diagramView.ZoomIn()
Case Keys.Subtract
diagramView.ZoomOut()
Case Keys.Z
If e.Modifiers = Keys.Control + Keys.Shift Then
diagram.UndoManager.Redo()
ElseIf e.Modifiers = Keys.Control Then
diagram.UndoManager.Undo()
End If
End Select
End Sub

Try this. Should behave the way you want it to, and it's a little simpler.
if (e.Control)
{
if (e.Shift && e.KeyCode == Keys.C)
{
//Do work
}
else if (e.KeyCode == Keys.V)
{
//Paste
}
}

Seeing as no one else mentions them, i'm just going to leave the suggestion to use KeyEventArgs.KeyData:
if (e.KeyData == (Keys.C | Keys.Control | Keys.Shift)
{
//do stuff
//potentially use e.Handled = true
}
if (e.KeyData == (Keys.V | Keys.Control)
{
//do other stuff
//potentially use e.Handled = true
}
This should only act on specific key combinations, though the order of the modifiers don't seem to matter, the first one is always the last pressed key.
And e.Handled = true should stop it, though i don't know the specific mechanics behind it.

Another approach more suitable if you have more cases, and easier to read is:
private void Form_KeyDown(object sender, KeyEventArgs e)
{
Action action = e.KeyData switch
{
(Keys.Control | Keys.Shift | Keys.C) => DoWork,
(Keys.Control | Keys.V) => Paste,
_ => null
};
action?.Invoke();
}
private void DoWork()
{ // do work }
private void Paste()
{ // paste }

Related

Disable Ctrl or Alt key without registry using c#

I got a question about KeyCode and disabling special keys. I know this question was asked a few times, but I didn't find an answer I can use and which works so I came here to ask :)
I'm writing a program which blocks every key or key combinations (like Alt+F4 etc.). The application is not for me, it's for customers which only be able to navigate in this program. This all works fine, but I can't disable Left CTRL, Right CTRL or Alt key. I got this code for try blocking these keys:
private void webBrowser1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.LControlKey)
{
MessageBox.Show("LCtrl", "Warnung", MessageBoxButtons.OK);
}
else if (e.KeyCode == Keys.RControlKey)
{
MessageBox.Show("RCtrl", "Warnung", MessageBoxButtons.OK);
}
else if (e.KeyCode == Keys.Alt)
{
MessageBox.Show("Alt", "Warnung", MessageBoxButtons.OK);
}
else if (e.KeyCode == Keys.Delete)
{
MessageBox.Show("Delete", "Warnung", MessageBoxButtons.OK);
}
}
I only use MessageBox.Show(); that I can see if it works. Delete key works fine, but the other one not. Is it possible to do this without editing the registry and for Win7? Does anyone know why or can give me a hint?
Cheers
EDIT: I block all other keys in this way:
Blocking shortcut keys using c#
Disclaimer: I'm not highly experienced in user input classes, but here's my input.
CTRL and ALT are examples of modifier keys. That is to say, they modify other (non-modifier) keys to create a key combination. Your UI is likely only able to pick up a complete key combination. For example:
private void keyPressed(object sender, PreviewKeyDownEventArgs e)
{
e.KeyCode == Key.A; // True (pressed A)
e.KeyCode == Key.Control; // False (no key pressed)
e.Modifiers == Keys.Control; // True (user is pressing the modifier CTRL)
e.KeyCode == Key.A && e.Modifiers == Keys.Control; (pressed key A with modifier CTRL)
}
As for disabling the key, you could just catch e.Modifiers:
private void ignoreCtrl(object sender, PreviewKeyDownArgs e)
{
if (e.Modifiers != Keys.Control) { /* Pass to handler */ }
else { /* Discard */ }
}
Again, I'm not experienced in your particular framework but this would be my guess. I used the following SO sources:
How to use multiple modifier keys in C#
Determine whether modifier key was pressed
This should be a comment because I have not tested it, but I need some code as example so I write here. You tell me if it works or not.
The PreviewKeyDownEventArgs contains other properties that you can use to check if one or more modifier keys are pressed.
You can then try to set the IsInputKey property to false to prevent further processing for whatever regular key has been pressed together the modifier key.
private void webBrowser1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
if (e.Control)
{
MessageBox.Show("Ctrl", "Warnung", MessageBoxButtons.OK);
e.IsInputKey = false;
}
else if (e.Alt)
{
MessageBox.Show("Alt", "Warnung", MessageBoxButtons.OK);
e.IsInputKey = false;
}
Have you tried checking the modifier keys? Such as below.
Note this is for WPF as you didnt state win forms or wpf.
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
MessageBox.Show("Control Button Down");
}
else if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt)
{
MessageBox.Show("Alt Down");
}
Cheers.

Control.ModifierKeys doesn't fire on Return/Enter key

I'm trying to detect when the user presses the Return key while in a Winforms textbox, but neither control statement below works when I use Keys.Enter and/or Keys.Return. It does work when I detect other keys such as Alt and Shift. What am I missing? They only vague lead that I have is that I'm testing this on a MacBook keyboard (running Windows), but surely those keys are mapped 100% correctly?
private void txtInput_KeyUp(object sender, KeyEventArgs e)
{
if ((Control.ModifierKeys == Keys.Enter))
{
btnOK_Click(null, null);
}
if ((Control.ModifierKeys & Keys.Return) != 0)
{
btnOK_Click(null, null);
}
}
Try using:
e.KeyCode == Keys.Enter
Control.ModifierKeys catch only if ctrl,alt,shift are pressed!
if you need catch only 'enter' pressed w/o any key pressed use:
e.KeyData == Keys.Enter

How to detect modifier key states in WPF?

Is there some global constructs that I can use whenever I need to access whether the Control, Shift, Alt buttons are down? For instance inside MouseDown event of a TreeView.
If so how?
Use class Keyboard. Using Keyboard.IsKeyDown you can check if Control, Shift, Alt is down now.
For Shift:
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{ /* Your code */ }
For Control:
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{ /* Your code */ }
For Alt:
if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{ /* Your code */ }
There's also:
// Have to get this value before opening a dialog, or user will have released the control key
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
}
private bool IsShiftKey { get; set; }
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
IsShiftKey = Keyboard.Modifiers == ModifierKeys.Shift ? true : false;
if ((Key.Oem3 == e.Key || ((IsShiftKey && Key.Oem4 == e.Key) || (IsShiftKey && Key.Oem6 == e.Key) || (IsShiftKey && Key.Oem5 == e.Key)) && (validatorDefn as FormatValidatorDefinition).format == "packedascii"))
{
e.Handled = true;
}
}
This is how I handle it (using PreviewKeyDown), let's say we are looking for Alt + R...
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)
&& e.SystemKey == Key.R)
{
//do whatever
}
}
Maybe someone can clear up why I had to use e.SystemKey and not just e.Key, maybe due to the modifier? but this has worked flawlessly for me when searching for modifier+key.
Partly borrowing from #Josh, and somewhat similar to #Krushik, and also referencing a question about the Difference between KeyEventArgs.systemKey and KeyEventArgs.Key (answering why Josh has to use SystemKey); wherein, with modifier keys (such as Alt), e.Key returns Key.System, and thus the 'real' key is within e.SystemKey.
A way around this, is to first fetch the 'real' key, and then do your conditional:
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
// Fetch the real key.
var key = e.Key == Key.System ? e.SystemKey : e.Key;
if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
&& key == Key.Return)
{
// Execute your code.
}
}
and as well:
if My.Computer.Keyboard.ShiftKeyDown then ...
My.Computer.Keyboard.CtrlKeyDown
My.Computer.Keyboard.AltKeyDown

c# capture Ctrl+PageUp keystroke

I am having trouble capturing Ctrl+PageUp keystroke in a ListView control in WinForms application.
I am using this code to capture keystrokes -
private void ListViewEx_KeyDown(object sender, KeyEventArgs e)
{
...
if(e.Control){
if((e.KeyCode ^ Keys.Left) == 0)
MessageBox.Show("Left"); //shows messagebox
else if((e.KeyCode ^ Keys.PageUp) == 0)
MessageBox.Show("PageUp"); //does not
...
}
Do I need to dive into WndProc to process this key? Thanks.
Edit: I've found out that this works, the problem was in enclosing TabControl handling these keys before ListControl got to them.
No need for WndProc:
if ((e.Modifiers & ModifierKeys) == Keys.Control && e.KeyCode == Keys.PageUp)
{
// ctrl + page up was pressed
}
The e.KeyData argument includes the modifier keys. Make it look like this:
if (e.KeyData == (Keys.Control | Keys.PageDown)) {
// Do your stuff
Console.WriteLine("Ctrl+PgDn");
}
check for
Keys.Control | Keys.PageUp

Detecting multiple simultaneous keypresses in C#

I am looking to emulate hyperterminal functionality for my Serial Communication in C# by detecting the keypresses of certain key combinations (escape sequences) which cannot be typed out such as Ctrl+C, Ctrl+Z, etc. I understand that these keys have their ASCII equivalents and can be transmitted as such. But I am facing problems with the detection of multiple keypresses. Some of my code is provided as a reference :
private void Transmitted_KeyDown(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.Control || e.Modifiers== Keys.Shift || e.Modifiers==Keys.Alt)
{
var test = (char)e.KeyValue; // Only able to detect a single keypress!
ComPort.Write(test.ToString());
}
}
If you're looking for regular keys then you can store them in a list: On KeyDown, add the key to a list. On Key Up, remove it from the list. On KeyDown, check what's in the list.
However, I'm not sure that there are keydown/keyup events for modifier keys like ctrl, shift, alt. For those you can do something like this:
bool CtrlDown = ((e.Modifiers & Keys.Control) > 0);
bool CtrlOnlyModifierDown = ((e.ModifierKeys & Keys.Control) == Keys.Control)
e.KeyCode contains the key value + modifier info
e.KeyCode = e.KeyValue | e.Modifiers
Use e.KeyCode
Not sure if you have had any luck.
But try this code:
switch (e.KeyData)
{
case Keys.Control:
{
if (e.KeyData == Keys.Subtract)
{ }
else if (e.KeyData == Keys.C)
{ }
break;
}
}

Categories

Resources