Logo
HOWTO: Create a checked/unchecked command in a Visual Studio add-in

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio .NET 2002
Date: May 2007   Microsoft Visual Studio .NET 2003
Updated: March 2013   Microsoft Visual Studio 2005
      Microsoft Visual Studio 2008
      Microsoft Visual Studio 2010
      Microsoft Visual Studio 2012

Introduction

This article explains how to create a command that, rather than to execute an action, is intended to be shown in two states: checked / unchecked.

More Information

To show a command in a checked / unchecked state, you need to use the IDTCommandTarget.QueryStatus to return the vsCommandStatus.vsCommandStatusLatched (checked) value.

The following code creates a command with a button in the Tools menu that can be checked / unchecked:

Imports System
Imports Microsoft.VisualStudio.CommandBars
Imports Extensibility
Imports EnvDTE
Public Class Connect
   Implements Extensibility.IDTExtensibility2
   Implements IDTCommandTarget
   Private Const MY_COMMAND_NAME As String = "MyCommand"
   Private m_applicationObject As EnvDTE.DTE
   Private m_addInInstance As EnvDTE.AddIn
   Private m_commandBarControl As CommandBarControl
   Private m_checked As Boolean = True ' The initial state
   Public Sub OnConnection(ByVal application As Object, ByVal connectMode _
      As Extensibility.ext_ConnectMode, ByVal addInInst As Object, _
      ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnConnection
      Try
         m_applicationObject = CType(application, EnvDTE.DTE)
         m_addInInstance = CType(addInInst, EnvDTE.AddIn)
         Select Case connectMode
            Case ext_ConnectMode.ext_cm_Startup
               ' The add-in was marked to load on startup
               ' Do nothing at this point because the IDE may not be fully initialized
               ' VS will call OnStartupComplete when ready
            Case ext_ConnectMode.ext_cm_AfterStartup
               ' The add-in was loaded after startup
               ' Initialize it in the same way that when is loaded on startup calling manually this method:
               OnStartupComplete(Nothing)
         End Select
      Catch e As System.Exception
         System.Windows.Forms.MessageBox.Show(e.ToString)
      End Try
   End Sub
   Public Sub OnStartupComplete(ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnStartupComplete
      Dim myCommand As Command = Nothing
      Dim toolsCommandBar As CommandBar
      Dim commandBars As CommandBars
      Try
         ' Try to retrieve the command, just in case it was already created
         Try
            myCommand = m_applicationObject.Commands.Item(m_addInInstance.ProgID & _
               "." & "MyCommand")
         Catch
         End Try
         ' Add the command if it does not exist
         If myCommand Is Nothing Then
            myCommand = m_applicationObject.Commands.AddNamedCommand(m_addInInstance, _
               "MyCommand", "MyCommand", "Executes the command for MyAddin", True, _
               59, Nothing, vsCommandStatus.vsCommandStatusSupported Or _
               vsCommandStatus.vsCommandStatusEnabled)
         End If
         ' Retrieve the collection of commandbars
         ' - In VS.NET 2002/2003 (which uses the Office.dll reference) 
         '   DTE.CommandBars returns directly a CommandBars type, so a cast 
         '   to CommandBars is redundant
         ' - In VS 2005 (which uses the new Microsoft.VisualStudio.CommandBars.dll reference) 
         '   DTE.CommandBars returns an Object type, so we do need a cast to CommandBars
         commandBars = DirectCast(m_applicationObject.CommandBars, CommandBars)
         ' Retrieve some built-in command bars
         toolsCommandBar = commandBars.Item("Tools")
         ' Create the buttons from the commands
         ' Note:
         ' - In VS.NET 2002/2003 (which uses the Office.dll reference) 
         '   Command.AddControl returns directly a CommandBarControl type, so a cast 
         '   to CommandBarControl is redundant
         ' - In VS 2005 (which uses the new Microsoft.VisualStudio.CommandBars.dll reference) 
         '   Command.AddControl returns an Object type, so we do need a cast to CommandBarControl
         ' Add a button to the built-in "Tools" menu
         m_commandBarControl = DirectCast(myCommand.AddControl(toolsCommandBar, _
            toolsCommandBar.Controls.Count + 1), CommandBarControl)
         m_commandBarControl.Caption = MY_COMMAND_NAME
      Catch e As System.Exception
         System.Windows.Forms.MessageBox.Show(e.ToString)
      End Try
   End Sub
   Public Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, _
      ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnDisconnection
      Try
         If Not (m_commandBarControl Is Nothing) Then
            m_commandBarControl.Delete()
         End If
      Catch e As System.Exception
         System.Windows.Forms.MessageBox.Show(e.ToString)
      End Try
   End Sub
   Public Sub OnBeginShutdown(ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnBeginShutdown
   End Sub
   Public Sub OnAddInsUpdate(ByRef custom As System.Array) _
       Implements Extensibility.IDTExtensibility2.OnAddInsUpdate
   End Sub
   Public Sub QueryStatus(ByVal cmdName As String, _
   ByVal neededText As vsCommandStatusTextWanted, _
   ByRef statusOption As vsCommandStatus, ByRef commandText As Object) _
   Implements IDTCommandTarget.QueryStatus
      If neededText = vsCommandStatusTextWanted.vsCommandStatusTextWantedNone Then
         If cmdName = m_addInInstance.ProgID & "." & MY_COMMAND_NAME Then
            If m_checked Then
               statusOption = CType(vsCommandStatus.vsCommandStatusEnabled + _
                  vsCommandStatus.vsCommandStatusSupported + _
                  vsCommandStatus.vsCommandStatusLatched, vsCommandStatus)
            Else
               statusOption = CType(vsCommandStatus.vsCommandStatusEnabled + _
                  vsCommandStatus.vsCommandStatusSupported + _
                  vsCommandStatus.vsCommandStatusEnabled, vsCommandStatus)
            End If
         Else
            statusOption = vsCommandStatus.vsCommandStatusUnsupported
         End If
      End If
   End Sub
   Public Sub Exec(ByVal cmdName 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 cmdName = m_addInInstance.ProgID & "." & MY_COMMAND_NAME Then
            handled = True
            m_checked = Not m_checked
            System.Windows.Forms.MessageBox.Show("Command executed. State changed.")
         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)