18

In C# (Microsoft Visual Studio 2010), how can I assign a keyboard shortcut to a button such as the following?

    private void closeButton_Click(object sender, EventArgs e)
    {
        // Close the program
        this.Close();
    }

I know I can use the "&" character in the button's Text and create an Alt - n shortcut, but I'd like to create a single keypress shortcut, such as c to execute the above.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tim S
  • 209
  • 1
  • 2
  • 7

3 Answers3

14

KeyDown is your friend ;) For example, if you want the shortcut key A while Shift is pressed, try this:

    void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.A && e.Shift) 
            // Do something
    }

If you want a "real" keyboard shortcut you can use hooks. Look at Stack Overflow question RegisterHotKeys and global keyboard hooks?.

Community
  • 1
  • 1
dknaack
  • 60,192
  • 27
  • 155
  • 202
  • Oo-er, is that really what WinForms makes you do? Makes VCL's TAction look pretty darned good. – David Heffernan Oct 21 '11 at 21:54
  • 3
    i am sorry, i cant understand you ;) please use other words. thanks in advance – dknaack Oct 21 '11 at 21:56
  • What I'm saying is that this is an incredibly laborious way to implement shortcuts compared to the facilities of the Delphi VCL which was after all the inspiration for WinForms. From what I can tell, WinForms is very lacking in terms of action handling. Perhaps WPF is better, I don't know. – David Heffernan Oct 21 '11 at 21:57
  • 3
    @dknaack: I think for your code to work, the form's `KeyPreview` property has to be set to `true`. – MusiGenesis Oct 21 '11 at 22:01
  • @David: I wouldn't call this syntax "laborious", exactly, mainly because wiring up keyboard shortcuts isn't something you have to do very often, anyway (maybe *you* have to do this a lot, in which case Delphi would have a definite appeal). – MusiGenesis Oct 21 '11 at 22:04
8

Here's a different approach:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    switch(keyData)
    {
         case Keys.F2:
             // do something...
             return true;
         case Keys.F3:
             // do something...
             return true;
         case Keys.F4:
             // do something...
             return true;
         default:
             return base.ProcessCmdKey(ref msg, keyData);
    }            
}

You don't need to change KeyPreview value.

The Berga
  • 3,744
  • 2
  • 31
  • 34
5

if you want add Ctrl + S in switch statment so you can also try below code.

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        switch (keyData)
        {
            case Keys.Control | Keys.S:
                // do something...
                return true;
            case Keys.Control |Keys.Alt | Keys.S:
                // do something...
                return true;
            case Keys.F2:
                // do something...
                return true;
            case Keys.F3:
                // do something...
                return true;
            case Keys.F4:
                // do something...
                return true;
            default:
                return base.ProcessCmdKey(ref msg, keyData);
        }
    }
Developer Guy
  • 2,318
  • 6
  • 19
  • 37
Rahul Patel
  • 291
  • 3
  • 4
  • This solution was better than using KeyDown for me, because it is fired wherever you are on the form. With KeyDown the event wasn't fired if the textbox was active. – Alex Russell May 13 '20 at 04:47