Click here to Skip to main content
15,893,588 members
Articles / Programming Languages / Visual Basic
Article

MnemonicTabControl - a tabcontrol with accelerator key support

Rate me:
Please Sign up or sign in to vote.
3.88/5 (7 votes)
19 Oct 20052 min read 79.8K   545   27   18
An ownerdrawn tabcontrol supporting accelerator keys to switch between tabs.

Sample Image - MnemonicTabControl.gif

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.

VB
' 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 TabPages 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).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalfeedback Pin
cinamon13-Aug-09 11:30
cinamon13-Aug-09 11:30 
QuestionWhy is this in C++ section? Pin
ChewsHumans4-Apr-08 9:16
ChewsHumans4-Apr-08 9:16 
AnswerRe: Why is this in C++ section? Pin
Stumpy84211-Apr-08 19:16
Stumpy84211-Apr-08 19:16 
GeneralRender issue Pin
CodeDownunder28-Aug-06 15:16
CodeDownunder28-Aug-06 15:16 
GeneralRe: Render issue Pin
Stumpy8421-Sep-06 9:20
Stumpy8421-Sep-06 9:20 
AnswerRe: Render issue Pin
CodeDownunder25-Sep-06 13:52
CodeDownunder25-Sep-06 13:52 
GeneralRe: Render issue Pin
Member 31971214-May-08 17:45
Member 31971214-May-08 17:45 
GeneralComments please! Pin
Stumpy84226-Oct-05 15:04
Stumpy84226-Oct-05 15:04 
GeneralRe: Comments please! Pin
fifthwheel28-Feb-06 6:00
fifthwheel28-Feb-06 6:00 
GeneralRe: Comments please! Pin
Stumpy84228-Feb-06 11:37
Stumpy84228-Feb-06 11:37 
GeneralRe: Comments please! Pin
fifthwheel28-Feb-06 16:46
fifthwheel28-Feb-06 16:46 
GeneralRe: Comments please! Pin
Chris Podmore2-Mar-06 3:11
Chris Podmore2-Mar-06 3:11 
GeneralRe: Comments please! Pin
Stumpy8422-Mar-06 15:55
Stumpy8422-Mar-06 15:55 
GeneralRe: Comments please! Pin
Lisa Liel26-Oct-06 9:40
Lisa Liel26-Oct-06 9:40 
GeneralRe: Comments please! Pin
bezorn16-May-06 12:14
bezorn16-May-06 12:14 
GeneralRe: Comments please! Pin
Stumpy84226-Oct-06 11:31
Stumpy84226-Oct-06 11:31 
QuestionRe: Comments please! Pin
mikeb5267-Jul-08 13:26
mikeb5267-Jul-08 13:26 
AnswerRe: Comments please! Pin
Stumpy8428-Jul-08 11:56
Stumpy8428-Jul-08 11:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.