DevCity.NET -
Adding Mnemonics (Short Cut Keys) to Your Controls
Chris Manning
I work as a professional .NET developer specializing in the areas of Windows Applications, Web Applications, and ADO.NET. I spend a good majority of my free time helping developers learn the .NET framework at vbCity and was recently awarded the Microsoft Visual Developer, Visual Basic MVP award. 
by Chris Manning
Published on 3/11/2005

Part 1 of a Multi-Part Series on Control Design. This article shows you how to add Mnemonics (shortcut keys) to a Custom Control. This is question I see quite a bit. There isn’t much out there on it.Web searches don’t turn up very much, and the experts on this kind of stuff seem to hold it pretty close.My own quest to learn this was frustrating to say the least.I had to piece and part little clues together until I figured it out.

The Core Class

Lets get started.


For this example we’re going to use a custom button control.  The buttons you see in most commercially available applications usually use Mnemonics and have short cut keys, so this will hit close to home and should be pretty easily understood by all, from the rookie programmer to some of the more experienced developers out there.


I’m not going to spend too much time on this part, but in a nut shell here is our core button class.  It’s inherited from a UserControl.  Make sure to add a reference to the System.Design.dll.


Imports System

Imports System.ComponentModel

Imports System.CompoenetModel.Design

Imports System.Drawing

Imports System.Drawing.Design

Imports System.Drawing.Drawing2D

Imports System.Windows.Forms.Design


<DEFAULTEVENT("CLICK"), DefaultProperty(?Text?)>_

Public Class MyBasicButton

            Inherits System.Windows.Forms.UserControl


            +[Windows Generated Code]



            Protected Overrides Sub OnPaint(ByVal e as PaintEventArgs)

                        Dim g as Graphics = e.Graphics

                        g.SmoothingMode = SmoothingMode.AntiAlias





            End Sub

            Private Sub PaintBorderAndText(ByVal g as Graphics)

                        Dim rect as New Rectangle(0, 0, Me.Width – 1, Me.Height – 1)

                        Dim rectf as New RectangleF(0, 0, Me.Width, Me.Height)

                        Dim sf as New StringFormat()


                        sf.Alignment = StringAlignment.Center

                        sf.LineAlignment = StringAlignment.Center

                        sf.HotKeyPrefix = System.Drawing.Text.HotKeyPrefix.Show

                        sf.Trimming = StringTrimming.EllipsesCharacter

                        sf.FormatFlags = StringFormatFlags.NoWrap


                        Dim b as Brush


                        ‘Draw the border

                        g.DrawRectangle(New Pen(Color.Black), rect)


                        Select Case m_State

                                    Case ButtonState.None

                                                b = New SolidBrush(Color.Black)

                                    Case ButtonState.Over

                                                b = New SolidBrush(Color.Blue)

                                    Case ButtonState.Clicked

                                                b = New SolidBrush(Color.Red)         

                        End Select


                        g.DrawString(m_Text, Me.Font, b, rectf, sf)

            End Sub

            Protected Overrides Sub OnMouseEnter(ByVal e as EventArgs)


                        m_State = ButtonState.Over


            End Sub

            Protected Overrides Sub OnMouseLeave(ByVal e as EventArgs)


                        m_State = ButtonState.None


            End Sub

            Protected Overrides Sub OnMouseDown(ByVal e as MouseEventArgs)


                        m_State = ButtonState.Clicked


            End Sub

            Protected Overrides Sub OnMouseUp(ByVal e as MouseEventArgs)


                        Select Case m_State

                                    Case ButtonState.Clicked

                                                m_State = ButtonState.Over

                                    Case ButtonState.Over

                                                m_State = ButtonState.None

                        End Select


            End Sub

            Protected Overrides Sub OnMove(ByVal e as EventArgs)



            End Sub

            Protected Overrides Sub OnResize(ByVal e as EventArgs)



            End Sub

            Private m_Text as String


            Public Overloads Overrides Property Text() as String


                                    Return m_Text

                        End Get

                        Set (ByVal value as String)

                                    m_Text = value


                        End Set

            End Property

            Private m_State as ButtonState = ButtonState.None


            Public Enum ButtonState as Integer

                        None = 0

                        Over = 1

                        Clicked = 2

            End Enum

End Class


































































































































































   So that’s the basic class.  As it stands right now, you should be able to compile the library, add it to your toolbox and a form and run the application.  The text should change colors during the mouse events of the button.  Nothing fantastic, but functional. 


   However, stop the debugging on the application and in the Text property type

“&Button”.  The “B” in button should be underlined.  Now run the project again and try to use the ALT + B keys.  Nothing happens right?



Adding the Mnemonics

Now to the core of this article;  Implementing Mnemonics in Custom Controls.


First we need to Implement an Interface.  So in your button class code, right after the Inherits System.Windows.Forms.UserControl, add


 Implements IButtonControl


There are now three(3) subsequent Subs / Functions we need to implement and one(1) Property.


If you’re like me, you try to keep the properties with the properties, the subs with the subs, etc.. In a class, however you can add these anywhere in the class.


First let's implement the NotifyDefault  Sub.  Nothing will actually happen here, but we have to add it to satisfy the "Implements IButtonControl"


 Public Sub NotifyDefault() Implements IButtonControl.NotifyDefault

            ‘Nothing Happens Here

End Sub


Next we’ll implement the DialogResult property.  The DialogResult property is like the dialog result property for any type of form, button, messagebox, open file dialog…anything.  It simply supplies the UI with a corresponding result for certain actions.


Private m_DialogResult as DialogResult

Public Property DialogResult() as DialogResult Implements IButtonContro.DialogResult


                        Return m_DialogResult

            End Get

            Set (ByVal value as DialogResult)

                        If [Enum].IsDefined(GetType(DialogResult), value) Then

                                    m_DialogResult = value

                        End If

            End Set

End Property

We now need to Implement the PerformClick method.  This is what allows the Mnemonic call to perform any actions associated with the OnClick method and the subsequent Click Event.


 Public Sub PerformClick() Implements IButtonControl.PerformClick


End Sub


And last but not least, the Function that does it all:-  ProcessMnemonic.  This is the function that determines which key combinations are being pressed while the UI the control is on is active.  .NET has a couple of built in functions that help us determine two things.

  1. Is the key that’s being pressed the Key that we want to process and therefore perform our actions.
  2. Is there a control key that’s being held.  Control keys are keys like Alt, Ctrl, Return, etc.

 Public Overrides Function ProcessMnemonic(ByVal c as Char) as Boolean

            If (Control.IsMnemonic(c, Me.Text) and (Control.ModifierKeys = Keys.Alt)) Then


                        Return true


            Return False

End If

End Function


And that’s it.  You should now be able to recompile your control. Add it to a form, run the form and press “Alt + ‘YourMnemonicKey’”.  Barring you have something in the Click event of the control, that event should fire.