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.