HOWTO: Create a keyboard shortcut (binding) to Visual Studio add-in command

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio 2005
Date: July 2013   Microsoft Visual Studio 2008
      Microsoft Visual Studio 2010
      Microsoft Visual Studio 2012

This article provides a sample to create a keyboard shortcut (binding) to a command from an add-in.

More Information

Visual Studio or add-in commands are represented by the EnvDTE.Command type, which has a Bindings property to get or set the keyboard shortcut(s). That property, although of type System.Object, is actually an array of System.Object, and each value is a String with the format "<scope>::<keys>", where the scope can be "Global", "Text Editor", etc. and the keys can include the modifiers Alt, Ctrl, Shift. You can see samples in the "Tools", "Options" menu, "Environment", "Keyboard" section.

Note: the scope must be localized if you are not using the English version of Visual Studio, but the key modifiers must be in English. See BUG: Command.Bindings causes Exception when setting value from an add-in in localized Visual Studio.

The following add-in creates a command and assigns it a keyboard shortcut.

Language: VB.NET   Copy Code Copy Code (IE only)
Imports System
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80

Public Class Connect
   Implements IDTExtensibility2
   Implements IDTCommandTarget

   Private Const COMMAND_NAME As String = "MyCommand"

   Private DTE As EnvDTE80.DTE2
   Private AddIn As EnvDTE.AddIn

   Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, _
      ByVal addInInst As Object, ByRef custom As Array) Implements IDTExtensibility2.OnConnection

      Me.DTE = CType(application, EnvDTE80.DTE2)
      Me.AddIn = CType(addInInst, EnvDTE.AddIn)

      Select Case connectMode

         Case ext_ConnectMode.ext_cm_AfterStartup

            ' The add-in has been loaded after Visual Studio was loaded. Since Visual Studio
            ' is fully initialized, we can initialize the add-in

         Case ext_ConnectMode.ext_cm_Startup

            ' The add-in has been loaded with Visual Studio. Do nothing until Visual Studio 
            ' is fully initialized (the OnStartupComplete method will be called)

         Case ext_ConnectMode.ext_cm_UISetup

            ' Do nothing in this case

      End Select

   End Sub

   Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete


   End Sub

   Private Sub InitializeAddIn()

      Dim command As EnvDTE.Command = Nothing

      ' Try to get if the command already exists
         command = Me.DTE.Commands.Item(Me.AddIn.ProgID & "." & COMMAND_NAME)
      End Try

      ' If the command doesn't exist, create it
      If command Is Nothing Then


            ' Create the command
            command = Me.DTE.Commands.AddNamedCommand(AddInInstance:=Me.AddIn, Name:=COMMAND_NAME, _
                ButtonText:=COMMAND_NAME, Tooltip:=COMMAND_NAME, MSOButton:=False)

            ' Assign the binding using the "Text Editor" scope. For a global scope use "Global::"
            ' Note: the scope must be localized, but the key modifiers must be in English
            command.Bindings = New Object() {"Text Editor::Ctrl+Shift+Alt+F"}

         Catch ex As Exception


         End Try

      End If

   End Sub

   Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef custom As Array) _
      Implements IDTExtensibility2.OnDisconnection
   End Sub

   Public Sub OnAddInsUpdate(ByRef custom As Array) Implements IDTExtensibility2.OnAddInsUpdate
   End Sub

   Public Sub OnBeginShutdown(ByRef custom As Array) Implements IDTExtensibility2.OnBeginShutdown
   End Sub

   Public Sub QueryStatus(ByVal commandName As String, ByVal neededText As vsCommandStatusTextWanted, _
      ByRef status As vsCommandStatus, ByRef commandText As Object) Implements IDTCommandTarget.QueryStatus

      If neededText = vsCommandStatusTextWanted.vsCommandStatusTextWantedNone Then

         If commandName = Me.AddIn.ProgID & "." & COMMAND_NAME Then

            status = vsCommandStatus.vsCommandStatusEnabled Or vsCommandStatus.vsCommandStatusSupported


            status = vsCommandStatus.vsCommandStatusUnsupported

         End If

      End If

   End Sub

   Public Sub Exec(ByVal commandName As String, ByVal executeOption As vsCommandExecOption, ByRef varIn As Object, _
      ByRef varOut As Object, ByRef handled As Boolean) Implements IDTCommandTarget.Exec

      handled = False

      If executeOption = vsCommandExecOption.vsCommandExecOptionDoDefault Then

         If commandName = Me.AddIn.ProgID & "." & COMMAND_NAME Then

            System.Windows.Forms.MessageBox.Show("Command executed")

            handled = True

         End If

      End If

   End Sub

End Class

Related articles

Go to the 'Visual Studio Extensibility (VSX)' web site for more articles like this (Articles section)