I have a Windows Form populated with a few controls. I want to let the user use the arrow keys to control some of the actions on the window. However, it seems like every time the user presses the arrow key, the controls (such as Button control) on the form receives the event and acts on it instead. How do I disable this behavior?
Answer
By default, special keys (such as Left, Right, Up, Down, etc) are filtered for focus management. That is to say, when you press the one of the arrow keys, Windows will automatically choose the next control on your form and set the focus on it. However, you can override this behavior by writing some code.
If your form has got no controls on it (or has controls that does not handle any keyboard inputs (such as the Panel control)), the easiest way would be to handle the KeyDown event of the form, like the following:
Private Sub Form1_KeyDown( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) _
Handles Me.KeyDown
If e.KeyData = Keys.Up Or _
e.KeyData = Keys.Down Or _
e.KeyData = Keys.Left Or _
e.KeyData = Keys.Right Then
'---perform your own action---
e.Handled = True
End If
End Sub
However, if the form contains controls that handles keyboard input (such as the TextBox and Button controls), then things get a little tricky.
Assuming you have some Button controls on your form and you want to disable the arrow keys having an effect on them. You need to do the following:
- Extend the Button control and override the IsInputKey function:
Public Class ExtendedButton
Inherits Button
Public Event ArrowClicked(ByVal key As Keys)
Protected Overrides Function IsInputKey( _
ByVal key As Keys) As Boolean
Select Case (key)
Case Keys.Up, Keys.Down, _
Keys.Left, Keys.Right
RaiseEvent ArrowClicked(key)
Return True
End Select
Return MyBase.IsInputKey(key)
End Function
End Class
- Programmatically add the extended Button control to your form:
Private Sub Form1_Load( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
Dim b1 As New ExtendedButton
With b1
.Text = "Button 1"
.Location = New Point(10, 20)
AddHandler .ArrowClicked, _
AddressOf ArrowClicked
End With
Me.Controls.Add(b1)
Dim b2 As New ExtendedButton
With b2
.Text = "Button 2"
.Location = New Point(100, 20)
AddHandler .ArrowClicked, _
AddressOf ArrowClicked
Me.Controls.Add(b2)
End With
End Sub
- Define the ArrowClicked event handler:
Public Sub ArrowClicked( _
ByVal key As Windows.Forms.Keys)
'---insert code here to do what
' you are supposed to do---
Console.WriteLine("key pressed " & _
key.ToString)
End Sub
That’s it! When the user now presses one of the arrow keys, the ArrowClicked event will be fired. You can insert the code to do whatever you are supposed to do here, such as animating some actions on your form, etc.