2

I got a form with a number of buttons on it (assume 20). In the middle, I got a User Control which is completely empty. The question is: how can I make it so that when the User Control is clicked, it will get keyboard focus?

Reason: I paint shapes in that User Control, with my mouse. The shapes are actually other User Controls. What I want to do is be able to use the keyboard to move those shapes. But I cannot seem to correctly be able to grab the Keyboard focus. The Key_Down events just don't reach my main (drawing into) User Control.

So, in other words, how can we have keyboard focus in a control has no focusable items on it? How can one make an keyboard-unfocusable control, catch those events? Any way of grabbing these events window-wide, other than going raw-WIN32 API hardcore?

Himanshu
  • 31,810
  • 31
  • 111
  • 133
Axonn
  • 10,076
  • 6
  • 31
  • 43

4 Answers4

6

A UserControl was very much designed to be a container control for other controls. It abhors getting the focus and tries to pass it off first chance it gets. You should not be using a UserControl here, given that you don't put any controls inside of it. A Panel control will suffice. Which has the exact same problem, it doesn't want to get focus either.

Surgery is required to override its behavior. Everything you need is in this answer.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Hello Hans and thank you for answering ::- ). I do add controls in it. Other User Controls. And I used a User Control (not a Panel) because I am custom-painting everything. I reviewed your answer in the other thread. Great stuff. You have a high score for a good reason ::- ). +2. – Axonn Nov 01 '10 at 16:57
1

Add this to your user control code to capture keyboard input:

    /// <summary>Keys which can generate OnKeyDown event.</summary>
    private static readonly Keys[] InputKeys = new []
        { Keys.Left, Keys.Up, Keys.Right, Keys.Down, };

    protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
    {
        if(Array.IndexOf<Keys>(InputKeys, e.KeyCode) != -1)
        {
            e.IsInputKey = true;
        }
        base.OnPreviewKeyDown(e);
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);
        // just to illustrate this works
        MessageBox.Show("KeyDown: " + e.KeyCode);
    }
max
  • 33,369
  • 7
  • 73
  • 84
0

See http://msdn.microsoft.com/en-us/library/aa969768.aspx. You can assign keyboard focus by 1. Set the usercontrol.Focusable=true; 2. Use Keyboard.Focus(usercontrol).

Wayne Lo
  • 3,689
  • 2
  • 28
  • 28
0

You need to set the CommandRouting flag on your control to true. The command routing dependency property is defined in a public API (MS.VS.Editor.dll) and your adornment will want to use that API to indicate that it is handling its commands instead of allowing the containing text view handle them. You can do this with from your control’s initialization. Microsoft.VisualStudio.Editor.CommandRouting.SetInterceptsCommandRouting(this, true);