MnemonicTabControl - a tabcontrol with accelerator key support






3.88/5 (7 votes)
Oct 19, 2005
2 min read

80666

546
An ownerdrawn tabcontrol supporting accelerator keys to switch between tabs.
Introduction
This control is based on a post by Mona Shukla - Microsoft Developer Support on .NET 247, originally written in C# and described as a MnemonicTabControl
. I've converted it to VB.NET and added several enhancements, such as a focus rectangle, HotTrack and disabled text and vertical tab alignment.
The Code
MnemonicTabControl
inherits System.Windows.Forms.TabControl
and overrides the ProcessMnemonic
and OnDrawItem
methods.
' Based on MnemonicTabControl class
' Original C# code posted by Mona Shukla - Microsoft Developer Support on .NET 247
' http://www.dotnet247.com/247reference/msgs/16/84624.aspx
' in microsoft.public.dotnet.framework.windowsforms
Public Class MnemonicTabControl
Inherits System.Windows.Forms.TabControl
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
Me.DrawMode = TabDrawMode.OwnerDrawFixed
End Sub
'UserControl overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<SYSTEM.DIAGNOSTICS.DEBUGGERSTEPTHROUGH()> Private Sub InitializeComponent()
components = New System.ComponentModel.Container
End Sub
#End Region
Private Const selfoc As Integer = DrawItemState.Selected Or DrawItemState.Focus
Private Const sel = DrawItemState.Selected
Private Const notsf As Integer = Not (selfoc Or DrawItemState.Default)
Protected Overrides Function ProcessMnemonic(ByVal charCode As Char) As Boolean
For Each p As TabPage In Me.TabPages
If Control.IsMnemonic(charCode, p.Text) Then
Me.SelectedTab = p
Me.Focus()
Return True
End If
Next p
Return False
End Function 'ProcessMnemonic
Protected Overrides Sub OnDrawItem(ByVal e As DrawItemEventArgs)
MyBase.OnDrawItem(e)
Dim g As Graphics = e.Graphics
Dim rectf As RectangleF
Dim vert As Boolean = (Me.Alignment > TabAlignment.Bottom)
Dim off As Integer = 1 : If (e.State And sel) = sel Then off = -1
Dim sf As New StringFormat(StringFormatFlags.NoClip _
Or StringFormatFlags.NoWrap)
With sf
.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show
.Alignment = StringAlignment.Center
.LineAlignment = StringAlignment.Center
End With
With e.Bounds
If vert Then
' tabs are aligned left or right
Dim m As New System.Drawing.Drawing2D.Matrix
m.Translate(0, .Height - Me.TabPages(0).Top)
m.RotateAt(270, New PointF(.X, .Y))
g.Transform = m
rectf = New RectangleF(.Left - Me.TabPages(0).Top, .Top + off, _
.Height, .Width)
Else
' tabs are aligned top or bottom
rectf = New RectangleF(.X, .Y + off, .Width, .Height)
End If
End With
Dim col As Color
Select Case (e.State And notsf)
Case DrawItemState.Disabled
col = SystemColors.GrayText
Case DrawItemState.HotLight
col = SystemColors.HotTrack
Case Else
col = SystemColors.MenuText
End Select
g.DrawString(Me.TabPages(e.Index).Text, _
Me.Font, _
New SolidBrush(col), _
rectf, _
sf)
If vert Then g.ResetTransform()
If (e.State And selfoc) = selfoc Then
ControlPaint.DrawFocusRectangle(g, _
[Rectangle].Inflate(e.Bounds, -1, -1))
End If
sf.Dispose()
End Sub 'OnDrawItem
End Class 'MnemonicTabControl
Usage
Add one or more instances of MnemonicTabControl
to your form. Set the HotTrack
property to True
, but leave the DrawMode
as OwnerDrawFixed
and the Appearance
as Normal
. The other properties may be set as needed. Then just use like a normal TabControl
, add TabPage
s and other child controls. Use the ampersand symbol in the TabPage
Text
property to set the mnemonic (also called accelerator) key for the tab.
When running your app, you can press ALT plus the defined key(s) to switch between tabs. If you're a keyboard fanatic like me, this is a real plus!
Limitations
I've not included support for images as found in the default TabControl
(hint: this would be a good challenge for somebody out there to enhance this control). The HotTrack feature uses the system's hot-tracking color defined in the system registry at the following key:
HKEY_CURRENT_USER\Control Panel\Colors
under the value HotTrackingColor
. It's a string of three numbers separated by spaces. The RGB values range from 0-255. Mine is currently set to the string "0 70 213". If you're adventurous, you could edit MnemonicTabControl
to add your own HotTrack color property.
Also, I'm cheating by using the fantastic visual support for XP provided by Skybound's VisualStyles control. If you don't have this free control in your collection, get it now! It is much easier and better than other means of achieving visual styles support for your app. It's free for use in both personal and commercial apps, but its use of unmanaged code will be a problem in partially trusted environments.
History
- 19 Oct 2005 - Initial release.
- 21 Oct 2005 - Revised code to correct orientation of vertical text (was top-down, now bottom-up to match .NET
TabControl
).