KeyDown : recognizing multiple keys
Asked Answered
C

13

42

How can I determine in KeyDown that CtrlUp was pressed.

private void listView1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Control && e.KeyCode == Keys.Up)
    {
        //do stuff
    }
}    

can't work, because never both keys are pressed exactly in the same second. You always to at first the Ctrl and then the other one...

Corrie answered 12/8, 2009 at 11:40 Comment(0)
D
34

You can check the modifiers of the KeyEventArgs like so:

private void listView1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Up && e.Modifiers == Keys.Control)
    {
        //do stuff
    }
}  

MSDN reference

Dehlia answered 12/8, 2009 at 11:44 Comment(4)
This is never true on my keyboard - for example, if I press down LShiftKey and Keys.Up, it e.Shift would never be true, and e.Modifiers would always stay None. Any idea why?Hydrate
It seems the arrow keys are special in some way. This question gives some insight: #1647498Dehlia
I only find there is e.Key but no e.KeyCode. There is also not e.Modifier.Cogen
@Cogen Confusingly, there's two different KeyEventArgs. I assume you're using the one from Windows.UI.Core, from the CoreWindow event. This answer is about a different event.Chaffin
L
16

From the MSDN page on KeyEventArgs:

if (e.KeyCode == Keys.F1 && (e.Alt || e.Control || e.Shift))
{
    //Do stuff...
}
Lusitania answered 12/8, 2009 at 11:44 Comment(0)
S
8

You can try using the Keyboard object to detect the IsKeyDown property. Also, if you don't want the browser shortcut to over-ride you can set Handled property to true.But be careful when over-riding browser shortcuts as it could cause confusion.

private void Page_KeyDown(object sender, KeyEventArgs e)
{
    // If leftCtrl + T is pressed autofill username
    if (Keyboard.IsKeyDown(Key.T) && Keyboard.IsKeyDown(Key.LeftCtrl))
    {
        txtUser.Text = "My AutoFilled UserName";
        e.Handled = true;
    }
}
Schuman answered 20/12, 2011 at 21:9 Comment(2)
Note: This is WPF.Coniology
@Coniology - We are running an XBAP Application (WPF running within Internet Explorer). So in that case you still need to useset the key stroke as Handled or IE will pick it up. XBAP isn't a very widely used framework, but I thought I'd let you know why I was discussing handling browsers at all :) - Thanks.Schuman
M
7

In the KeyEventArgs there are properties Ctrl, Alt and Shift that shows if these buttons are pressed.

Musick answered 12/8, 2009 at 11:45 Comment(1)
Thank you This worked perfect! if(e.Control && e.KeyCode == Keys.A)Divertissement
G
4
private void listView1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Up && Keyboard.IsKeyDown(Key.LeftCtrl))
    {
         //do stuff
    }
}

This code will work only if you press first LeftCtrl, then "UP". If order has no importance, I recommend that one :

if ((Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))&& Keyboard.IsKeyDown(Key.Z))
{
    //do stuff
}

In that case, both Ctrl are taken in account, and no importance about the order.

Gentlewoman answered 28/11, 2017 at 2:41 Comment(0)
N
3

You can use the ModifierKeys property:

if (e.KeyCode == Keys.Up && (ModifierKeys & Keys.Control) == Keys.Control)
{
    // CTRL + UP was pressed
}

Note that the ModifierKeys value can be a combination of values, so if you want to detect that CTRL was pressed regardless of the state of the SHIFT or ALT keys, you will need to perform a bitwise comparison as in my sample above. If you want to ensure that no other modifiers were pressed, you should instead check for equality:

if (e.KeyCode == Keys.Up && ModifierKeys == Keys.Control)
{
    // CTRL + UP was pressed
}
Natatorial answered 12/8, 2009 at 11:45 Comment(2)
Over HERE, you said that data is in the KeyData field. No one here has mentioned KeyData. Are these answers incorrect?Corgi
Good catch @jp2code! ModifierKeys is a property on Control (such as a windows forms form) that will give you information on what modifier keys that are currently being pressed. KeyData that comes with the key events contains information about what modifier keys that were pressed together with the key that caused the event. In retrospect, I'd say that ModifierKeys is more interesting together with button click or similar events, and that it would be more accurate to use KeyData during key events.Denims
C
0

this will work for sure. Be careful to handle KeyUp event and not keyDown.

private void mainForm_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.Modifiers == Keys.Control && e.KeyCode == Keys.A)
        {
             //insert here
        }
    }

For me, keyDown didn't work, keyUp worked instead for the same code.

I don't know why, but it seems because keyDown event happens directly after you press any key, even if that was ctrl key, so if you pressed ctrl+Up you will press ctrl key before the UP key and thus the event will occur before you can press the other, also pressing the second key will triggers the event again.

While using KeyUp will not trigger the event until you release the key, so you can press ctrl, and the press the second key, which will trigger one event.

Cambodia answered 2/1, 2016 at 17:51 Comment(0)
A
0

I tested below code. it works...

private void listView1_KeyDown(object sender, KeyEventArgs e)
    {
        if ((int) e.KeyData == (int) Keys.Control + (int) Keys.Up)
        {
            MessageBox.Show("Ctrl + Up pressed...");
        }
    }
Aholla answered 29/1, 2019 at 8:30 Comment(0)
B
0

It took me a while to find the hint I ultimately needed when trying to detect [Alt][Right]. I found it here: https://social.msdn.microsoft.com/Forums/vstudio/en-US/4355ab9a-9214-4fe1-87ea-b32dfc22946c/issue-with-alt-key-and-key-down-event?forum=wpf

It boils down to something like this in a Shortcut helper class I use:

public Shortcut(KeyEventArgs e) : this(e.Key == System.Windows.Input.Key.System ? e.SystemKey : e.Key, Keyboard.Modifiers, false) { }

public Shortcut(Key key, ModifierKeys modifiers, bool createDisplayString)
{
    ...
} 

After "re-mapping" the original values (notice the e.Key == System.Windows.Input.Key.System ? e.SystemKey : e.Key part), further processing can go on as usual.

Borchers answered 12/5, 2019 at 22:41 Comment(0)
B
0

if (e.Control && e.Shift && e.KeyCode == Keys.A) {

}

Bruiser answered 25/11, 2019 at 7:28 Comment(1)
When answering an old post, it would be helpful if you could provide some context to your answer rather than just code, as it might make it more useful to others.Scleroderma
K
0

The KeyDown event will only hold the information for the most recent key that was pressed. I have had success building a string that contains all the most recent key down keys concatenated together.

If a key down of "Control" was clicked, or the strings becomes greater than 10 chars long, I clear the string.

Checking the string each time, then performing a task afterwords gives a great use for a secret hotkey function within your application.

    private void ConfigurationManager_KeyDown(object sender, KeyEventArgs e)
    {
        string currentKey = e.KeyCode.ToString().ToLower();

        if ((currentKey == "controlkey") || (hotKeyList.Length > 10))
        {
            hotKeyList = "";
        }
        else
        {
            hotKeyList += currentKey;
        }

        if ((hotKeyList == "int") && (!adminLogin))
        {
            hotKeyList = "";
            adminLogin = true;
            AdminLoginEvn();
        }
    }

For the function above my hotkeys would be "Control (clears the string) + i + n + t" to fire my AdminLoginEvn method. The adminLogin boolean was incorporated so I only run my AdminLoginEvn one time while the application is open.

Kliman answered 15/6, 2020 at 19:56 Comment(0)
L
-1

you can try my working code :

private void listView1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Up)
    {
        if(e.Alt==true){
            //do your stuff
        }
    }
}

i use this code because i don't know why when i use :

(e.Keycode == Keys>up && e.Alt==true)

didn't work.

Linwoodlinz answered 12/1, 2017 at 10:14 Comment(0)
O
-2

you have to remember the pressed keys (ie in a bool array). and set the position to 1 when its pressed (keydown) and 0 when up .

this way you can track more than one key. I suggest doing an array for special keys only

so you can do:

 if (e.KeyCode == Keys.Control)
 {
        keys[0] = true;
 }
// could do the same with alt/shift/... - or just rename keys[0] to ctrlPressed

if (keys[0] == true && e.KeyCode == Keys.Up)
 doyourstuff
Outflow answered 12/8, 2009 at 11:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.