The Issue
Sometimes, in our applications, it would be helpful to assign a specialized meaning to the use of the Tab key. That is, rather than the normal action of changing the focus to the next control on the tab-order, one might wish the Tab key to cause some other action or event.
For instance, in one of my applications, I wanted to use the Tab key to cause the program to display the next group of images (or the previous group, if Shift-Tab is pressed). Now, of course, I could use the PageUp and PageDown keys for these functions, but -- assuming a right-handed user moving the mouse with his right hand -- that would require the user to "waste" time moving between the mouse and the keyboard. One purpose of this particular application is to allow a quick visual inspection of perhaps several hundred images (per order), and we want to spend the minimum of time on each order.
The Unfortunate Complication
"No problem," I thought. At first. "I'll just use the protected override void OnKeyDown(KeyEventArgs args)
method to determine that the user has used the Tab key."
Unfortunately, under normal circumstances, the Tab key does not make it into the OnKeyDown()
and related methods. I say "normal circumstances" because I've noticed that one way of coding the methodology described here will cause the Tab key to reach the OnKeyDown()
method.
The Fortunate Resolution
Fortunately, in the base Form
class, there exists the protected override bool ProcessTabKey(bool forward)
method. Using this method, we can intercept and "consume" the Tab key.
And, as it turns out, if the ProcessTabKey()
method's return value is false
, the Tab key does make it into the OnKeyDown()
method. But, of course, if your code "consumes" the Tab key in the ProcessTabKey()
method, you probably won't need to process it in the OnKeyDown()
method.
Also, the Control-Tab combination makes it into the OnKeyDown()
method.
So, knowing these things, we are prepared to define a customized use for the Tab key -- and we can code the form to allow the user to use the Control-Tab combination to toggle between the normal use/meaning of the Tab key and our custom use.
C# Example Code
Keep in mind that you'll generally want to set the form's .KeyPreview
property to true
(depending on the content of the form, this may not be necessary).
private void InitializeComponent()
{
this.KeyPreview = true;
}
#region Overridden Methods: [OnKeyDown()] and
[ProcessTabKey()] -- Intercept/process [Keys.Tab]
protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs args)
{
if( (args.Modifiers == System.Windows.Forms.Keys.Control)
&& (args.KeyCode == System.Windows.Forms.Keys.Tab) )
{
interceptTabKey = !interceptTabKey;
}
base.OnKeyDown(args);
}
private bool interceptTabKey = true;
protected override bool ProcessTabKey(bool forward)
{
if (interceptTabKey)
{
if (forward)
{
}
else
{
}
return true;
}
return base.ProcessTabKey(forward);
}
#endregion
Visual Basic Example Code
Keep in mind that you'll generally want to set the form's .KeyPreview
property to True
(depending on the content of the form, this may not be necessary).
Private Sub InitializeComponent()
Me.KeyPreview = True
End Sub
#Region "Overridden Methods: [OnKeyDown()] and
[ProcessTabKey()] -- Intercept/process [Keys.Tab]"
Protected Overrides Sub OnKeyDown(ByVal args As System.Windows.Forms.KeyEventArgs)
If args.Modifiers = System.Windows.Forms.Keys.Control _
And args.KeyCode = System.Windows.Forms.Keys.Tab Then
If interceptTabKey Then
interceptTabKey = False
Else
interceptTabKey = True
End If
End If
MyBase.OnKeyDown(args)
End Sub
Dim interceptTabKey As Boolean = True
Protected Overrides Function ProcessTabKey(ByVal forward As Boolean) As Boolean
If interceptTabKey Then
If forward Then
Else
End If
Return True
End If
Return MyBase.ProcessTabKey(forward)
End Function
#End Region