1

I need to associate Ctrl+Z key combination to a custom form action (Undo).

I handle Me.KeyDown event, but don't receive it each time I press keys. Perhaps it depends of what currently active control in a form I have.

As I read from this article I need to

  Private Sub MyForm_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
    e.Handled = True
  End Sub

but even this event I don't receive but when having some controls focused, but not others.

  • More that than, for the TextBoxes I can't modify the text anymore;
  • More that than, for the TextBoxes there is a (Windows?) Undo-Redo default mechanism, that should work too.
  • What should I do to always recieve the KeyDown event on the form?
serhio
  • 28,010
  • 62
  • 221
  • 374

5 Answers5

4

You can override ProcessCmdKey to handle key presses on the form level.

See this question for more details and examples: Hotkey (not global) in Windows Forms .NET

Community
  • 1
  • 1
unholysampler
  • 17,141
  • 7
  • 47
  • 64
2

You need to set the KeyPreview property of your form to true so that your form will receive the key events for all controls on the form. That way, your shortcuts should work no matter what control currently has focus. Here is a quick example you can play with to test this out. Create a new form with several different controls on it and modify the code like so:

public Form1()
{
    InitializeComponent();

    KeyPreview = true;  // indicates that key events for controls on the form
                        // should be registered with the form

    KeyDown += new KeyEventHandler(Form1_KeyDown);
}

void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Modifiers == Keys.Control)
    {
        switch (e.KeyCode)
        {
            case Keys.A:
                MessageBox.Show("Ctrl + A was pressed!");
                break;
            case Keys.C:
                MessageBox.Show("Ctrl + C was pressed!");
                break;
            case Keys.V:
                MessageBox.Show("Ctrl + V was pressed!");
                break;
        }
    }
}

No matter what control has focus when you enter the key combinations, your form's Form1_KeyDown method will be called to handle it.

jwnace
  • 360
  • 3
  • 11
  • Sorry, I just realized that your code sample is VB and I gave you an example in C#. – jwnace Jan 17 '11 at 17:00
  • Sorry, originally my example was written using KeyUp and then I changed it when I realized that you talked about using KeyDown. – jwnace Jan 17 '11 at 17:16
1

If your form has a menu then you could create an Undo MenuItem and set it's Shortcut properties to the desired key combo.

T3hc13h
  • 602
  • 6
  • 15
0
  1. Sounds to me like you are wanting a global hook into what keys are pressed.

  2. If you do it the way you started, then you will have to handle the keypress/keydown event of every control on a form (or each form).

EDIT

If you use the KeyPress event mixed with the e.handled = true, that might get you where you want to be. Setting handled to true should mean that the form receives all of the events instead of the individual controls. If you then use the KeyPress event to handle the Ctrl+Z, then you should be able to run your custom command on a form regardless of what control has focus (according to the documentation).

Community
  • 1
  • 1
Tony Abrams
  • 4,505
  • 3
  • 25
  • 32
  • well the problem there is that I don't think you can without handling the keypress/keydown event of each control on a form. – Tony Abrams Jan 17 '11 at 16:33
  • How about differences between `PreviewKeyDown` and `KeyDown`? – serhio Jan 17 '11 at 16:37
  • The biggest differences are when they occur (KeyDown, KeyPress then KeyUp) and that the KeyPress event is not raised by noncharacter keys, but KeyDown/KeyUp is triggered by noncharacter keys. – Tony Abrams Jan 17 '11 at 16:45
-1
 Private Sub form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        KeyPreview = True
    End Sub
ridoy
  • 6,274
  • 2
  • 29
  • 60
emilio
  • 1