rfairhur24

Add-In Application Extension Behavior at ArcMap Startup

Discussion created by rfairhur24 on Nov 8, 2011
Just for anyone's information, I have been on the phone with ESRI support and after many hours gotten an Add-In Application Extension to behave the way I wanted when its original AutoLoad property is set to False (the default wizard setting for an Application Extension).  I found that after the initial time the extension is used, whatever state the user left the Extension Manager in or the add-in UI element (dockable window open, button customized to a toolbar) is persisted when ArcMap is closed and will reappear in that state the next time ArcMap is opened.

If you have tried the Custom Selection Extension sample, you might be led to believe that the extension checks to see if it is enabled automatically when ArcMap restarts, since this code appears to automatically fire the Extension's OnStartup method.  However, this is not really the case.  If the user left an Add-In Application Extension enabled when they closed ArcMap the OnStartup() method only fires if it is triggered by specific code contained in a UI Add-in type that fires its New method the next time ArcMap is opened.  In the sample above this is only accomplished if the toolbar opens immediately when ArcMap starts.  In that case, the toolbar registers its Add-in components, which in turn fire code to check the extension state, which then makes the extension actually fire it's Startup Method as ArcMap opens.

Anyway, if everytime ArcMap starts you want an Add-In dockable window the user left open to check to see if the Add-In Application Extension is enabled here is my suggested minimum code for the Dockable Window (all the code below will do is switch visibility between a label and a combobox on the dockable window depending on the Extension state when ArcMap opens or the extension is enabled or disabled in the Extension Manager):

Public Class MyDockableWindow
  Inherits UserControl
  Private Shared s_label As Label
  Private Shared s_combobox1 As System.Windows.Forms.ComboBox
  Private Shared s_enabled As Boolean

  Public Sub New(ByVal hook As Object)
    InitializeComponent()
    Me.Hook = hook
    s_label = label1 ' set a shared variable to a label on the dockable window
    s_comboBox1 = comboBox1 ' set a share variable to a combobox on the dockable window
    ' Have the extension check its enabled status
    MyExtension.IsExtensionEnabled() ' replace "MyExtension" with your actual extension name.
  End Sub

  ' Method called by the extension to set the state of the dockable window
  Friend Shared Sub SetEnabled(ByVal enabled As Boolean)
    MyExtension.IsExtensionEnabled()
    s_enabled = enabled

    ' if the dockable window was never displayed, combobox could be null
    If s_combobox Is Nothing Then
      Return
    End If

    If enabled Then
      s_label.Visible = False ' label saying extension is disabled appears
      s_combobox1.Visible = True ' a combobox control appears if the extension is enabled
    Else
      s_label.Visible = True ' Label saying extension is disabled disappears
      s_combobox1.Visible = False ' a combobox control disappears if the extension is disabled
    End If
End Sub
  ''' <summary>
  ''' Host object of the dockable window
  ''' </summary>
  Private privateHook As Object

' Standard code added by the Add-In dockable wizard
End Class


Then in the Add-In Application Extension here is my minimum suggested code:

Public Class MyExtension ' replace with actual extension name
  Inherits ESRI.ArcGIS.Desktop.AddIns.Extension
  Private Shared s_dockWindow As ESRI.ArcGIS.Framework.IDockableWindow
  Private Shared s_extension As MyExtension ' replace with actual extension name

  ' Overrides
  Protected Overrides Sub OnStartup()
    s_extension = Me

    ' Wire up events. Example events are commented below.  They require additional code.
    ' AddHandler ArcMap.Events.NewDocument, AddressOf ArcMap_NewOpenDocument
    ' AddHandler ArcMap.Events.OpenDocument, AddressOf ArcMap_NewOpenDocument

    Initialize()
  End Sub

  Protected Overrides Sub OnShutdown()
    Uninitialize()

    ' Reverse whatever events you wired up.  Examples events are below  They require additional code.
    ' RemoveHandler ArcMap.Events.NewDocument, AddressOf ArcMap_NewOpenDocument
    ' RemoveHandler ArcMap.Events.OpenDocument, AddressOf ArcMap_NewOpenDocument

    s_dockWindow = Nothing
    s_extension = Nothing

    MyBase.OnShutdown()
  End Sub
  
   Private Sub Initialize()
    If s_extension Is Nothing Or Me.State <> ExtensionState.Enabled Then
      Return
    End If

    ' Reset event handlers.  Examples are commented below.  They require additional code.

    ' Dim avEvent As IActiveViewEvents_Event = TryCast(ArcMap.Document.FocusMap, IActiveViewEvents_Event)
    ' AddHandler avEvent.ItemAdded, AddressOf AvEvent_ItemAdded
    ' AddHandler avEvent.ItemDeleted, AddressOf AvEvent_ItemAdded
    ' AddHandler avEvent.ContentsChanged, AddressOf avEvent_ContentsChanged

    ' Update the UI
    MyDockableWindow.SetEnabled(True)
  End Sub

  Private Sub Uninitialize()
    If s_extension Is Nothing Then
      Return
    End If

    ' Detach event handlers.  Examples are commented below.
    
    ' Dim avEvent As IActiveViewEvents_Event = TryCast(m_map, IActiveViewEvents_Event)
    ' RemoveHandler avEvent.ItemAdded, AddressOf AvEvent_ItemAdded
    ' RemoveHandler avEvent.ItemDeleted, AddressOf AvEvent_ItemAdded
    ' RemoveHandler avEvent.ContentsChanged, AddressOf avEvent_ContentsChanged
    ' avEvent = Nothing

     ' Update the UI
     MyDockableWindow.SetEnabled(False)
  End Sub

  Friend Shared Function GetDockableWindow() As ESRI.ArcGIS.Framework.IDockableWindow
    If s_extension Is Nothing Then
      GetExtension()
    End If

    ' Only get/create the dockable window if they ask for it
    If s_dockWindow Is Nothing Then
      Dim dockWinID As UID = New UIDClass()
      dockWinID.Value = ThisAddIn.IDs.MyDockableWindow
      s_dockWindow = ArcMap.DockableWindowManager.GetDockableWindow(dockWinID)
    End If

    Return s_dockWindow
  End Function

  Protected Overrides Function OnSetState(ByVal state As ExtensionState) As Boolean
    ' Optionally check for a license here
    Me.State = state

    If state = ExtensionState.Enabled Then
      Initialize()
    Else
      Uninitialize()
    End If

    Return MyBase.OnSetState(state)
  End Function

  Protected Overrides Function OnGetState() As ExtensionState
    Return Me.State
  End Function

  Friend Shared Function IsExtensionEnabled() As Boolean
    If s_extension Is Nothing Then
      GetExtension()
    End If

    If s_extension Is Nothing Then
      Return False
    End If

    Return s_extension.State = ExtensionState.Enabled
  End Function

  Private Shared Function GetExtension() As MyExtension ' replace the "MyExtension" type with your actual extension's name
    If s_extension Is Nothing Then
      Dim extID As UID = New UIDClass()
      extID.Value = ThisAddIn.IDs.MyExtension  ' replace the "MyExtension" type with your actual extension's name
      ' Call FindExtension to load this just-in-time extension.
      ArcMap.Application.FindExtensionByCLSID(extID)
    End If
    Return s_extension
  End Function
End Class


Finally here is a button to launch the dockable window.

Public Class MyButton
  Inherits ESRI.ArcGIS.Desktop.AddIns.Button

  Public Sub New()

  End Sub

  Protected Overrides Sub OnClick()
    Dim dockWindow As ESRI.ArcGIS.Framework.IDockableWindow
    dockWindow = MyExtension.GetDockableWindow()
    If dockWindow Is Nothing Then
      Return
    End If
    dockWindow.Show((Not dockWindow.IsVisible()))
  End Sub

  Protected Overrides Sub OnUpdate()
    Me.Enabled = MyExtension.IsExtensionEnabled()
  End Sub
End Class

Outcomes