2

I'm using WinForms. I've created an event handler for the KeyDown event of the main form, thereby invoking a button's Click event handler.

The Click event handler called is dependent upon the specific key pressed. If a user clicks the button rather than using the key, and then subsequently tries to use the key thereafter, the key (down arrow for example) acts as a tab-cycle, changing focus between each button control on the form (rather than executing the Keydown handler).

Any ideas ?

4 Answers 4

2

The problem is, the button has the focus when it is clicked, so subsequent key presses are not caught by the form itself, but by the buttons instead. In the click event handler for the buttons, focus the form:

this.Focus(); 

That way, focus is restored to the form so the form will listen for the keypress events.

Edit

The real problem, as you have discovered, is that arrow keys are not treated as input keys. To fix this, you need to create a new class that inherits whatever control you want to use. Then, you override the IsInputKey method to treat arrow keys as input keys. Check this link: http://bytes.com/topic/c-sharp/answers/517530-trapping-arrow-keys-usercontrol. This article is also useful: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.isinputkey.aspx.

Sign up to request clarification or add additional context in comments.

Comments

2

As per SimpleCoder, I had to override the IsInputKey member for the Button class.

public class ControlButton : Button { protected override bool IsInputKey(Keys keyData) { if (keyData == Keys.Up) { return true; } else if (keyData == Keys.Down) { return true; } else if (keyData == Keys.Left) { return true; } else if (keyData == Keys.Right) { return true; } else { return base.IsInputKey(keyData); } } } 

Then I needed to instantiate my button objects (in the designer class) using this new class, like so:

 private ControlButton btnDown; private ControlButton btnRight; private ControlButton btnLeft; private ControlButton btnUp; this.btnDown = new ControlButton(); this.btnRight = new ControlButton(); this.btnUp = new ControlButton(); this.btnLeft = new ControlButton(); 

Next I registered OnClick handlers for each of the new button objects like so:

 this.btnUp.Click += new System.EventHandler(this.btnUp_Click); private void btnUp_Click(object sender, EventArgs e) { MessageBox.Show("Up"); } 

(etc.)

And registered a KeyDown handler for the main form:

 this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.frmUavController_KeyDown); private void frmUavController_KeyDown(object sender, KeyEventArgs e) { if ((e.KeyCode == Keys.Up) || (e.KeyCode == Keys.W)) { btnUp.PerformClick(); } else if ((e.KeyCode == Keys.Down) || (e.KeyCode == Keys.S)) { btnDown.PerformClick(); } else if ((e.KeyCode == Keys.Left) || (e.KeyCode == Keys.A)) { btnLeft.PerformClick(); } else if ((e.KeyCode == Keys.Right) || (e.KeyCode == Keys.D)) { btnRight.PerformClick(); } } 

Having set the main form property KeyPreview to true, and seeing as though I had overridden the default behaviour of the Up, Down, Left and Right keys, the button controls no longer cycle focus, but rather return true, transferring control back to the main form. From here, if subsequent keys (up, down, left or right) are pressed, the form actions the appropriate handler.

1 Comment

Please use a switch statement for stuff like this. It hurts my eyes.
0

Use Control.GetNextControl and Set Focus to what it returns.

6 Comments

I think he's trying to prevent this behavior, although the question is pretty vague.
From what I understand wulfgarpro wants to catch KeyDown of the form, when button is in focus and arrow buttons are pressed.
Yes I am trying to prevent that behavior. Sorry the question is vague.. I cant explain it any clearer.
Set the TabStop of the controls to false may be ? I'm sorry I'm not able to understand the question / requirement
Setting TabStop to false doesn't help with arrow key navigation.
|
0

Look at KeyPreview property. http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx

Set it to true.

Or alternatively you may want to override ProcessKeyPreview of the form.

3 Comments

@upvoter: does this work for you? No effect for me on .NET 4. Is there some additional step to take?
After reading manual, KeyPreview is for key events. Not for tabs, arrows ... Sorry for confusing. Overriding ProcessKeyPreview should help. You may find some ideas here - codeproject.com/KB/cs/ProcessKeyPreview.aspx?msg=2375387.
I currently have the KeyPreview property set to true for the form; when the user clicks one of the buttons (rather than using the defined key), the form loses focus and the KeyDown event becomes associated with the button (which now has focus). I therefore created the same KeyDown event handler that the form uses for the button. This doesn't stop the arrow key from acting as a mechanism to toggle focus between other buttons on the form. I need a way to stop the default behaviour of the arrow keys when a button has focus.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.