Logo
HOWTO: Detect when a Visual Studio toolwindow is shown or hidden.

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio 2005
Date: August 2011   Microsoft Visual Studio 2008
Updated: March 2013   Microsoft Visual Studio 2010
      Microsoft Visual Studio 2012
Introduction

Once created, toolwindows are never destroyed (or "closed", as happens with document windows). When you click the "Close" button of a toolwindow, it is hidden (made invisible). When you show it again, it is made visible again (but not re-created because it was not destroyed). See the article HOWTO: Create a dockable toolwindow from a Visual Studio .NET add-in.

So, the EnvDTE.WindowEvents class and its WindowCreated and WindowClosing events can't be used with toolwindows. And since they are not document windows, the EnvDTE.DocumentEvents class with the DocumentOpening, DocumentOpened and DocumentClosing events can't be used either.

The automation model of Visual Studio 2005 (EnvDTE80) introduced the new EnvDTE80.WindowVisibilityEvents class with the WindowShowing and WindowHiding events, that allow you to detect when any window (document window or toolwindow) of Visual Studio is shown or hidden.

To use that class and events you must take into account the following:

  • To get an instance of the WindowVisibilityEvents class from the EnvDTE.DTE object, you must cast the DTE.Events property to EnvDTE80.Events2.
  • The EnvDTE80.Events2.WindowVisibilityEvents property has an optional EnvDTE.Window parameter to get the visibility events of a particular window. If omitted, the visibility events of all windows are received.
  • When getting events of all windows, see the article HOWTO: Getting information about Visual Studio windows from an add-in to identify when a EnvDTE.Window is a toolwindow, and which one.

The following sample shows an add-in that detects when any toolwindow is shown or hidden:

Language: C#   Copy Code Copy Code (IE only)
using Extensibility;
using EnvDTE;
using EnvDTE80;

namespace MyAddin1
{
   public class Connect : Extensibility.IDTExtensibility2
   {
      private EnvDTE.DTE applicationObject;
      private EnvDTE.AddIn addInInstance;
      private EnvDTE80.WindowVisibilityEvents windowVisibilityEvents;
      
      public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
      {
         try
         {
            applicationObject = (EnvDTE.DTE)application;
            addInInstance = (EnvDTE.AddIn)addInInst;

            switch (connectMode)
            {
               case ext_ConnectMode.ext_cm_UISetup:

                  // Do nothing
                  break;

               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
                  // Visual Studio will call OnStartupComplete when fully initialized
                  break;

               case ext_ConnectMode.ext_cm_AfterStartup:

                  // The add-in was loaded by hand after startup using the Add-In Manager
                  // Initialize it in the same way that when is loaded on startup
                  InitializeAddIn();
                  break;
            }
         }
         catch (System.Exception e)
         {
            System.Windows.Forms.MessageBox.Show(e.ToString());
         }
      }

      public void OnStartupComplete(ref System.Array custom)
      {
         InitializeAddIn();
      }

      public void InitializeAddIn()
      {
         EnvDTE80.Events2 events2;

         events2 = (EnvDTE80.Events2)applicationObject.Events;

         windowVisibilityEvents = events2.get_WindowVisibilityEvents();

         windowVisibilityEvents.WindowShowing += new _dispWindowVisibilityEvents_WindowShowingEventHandler(
            windowVisibilityEvents_WindowShowing);
         windowVisibilityEvents.WindowHiding += new _dispWindowVisibilityEvents_WindowHidingEventHandler(
            windowVisibilityEvents_WindowHiding);
      }

      public void OnDisconnection(Extensibility.ext_DisconnectMode RemoveMode, ref System.Array custom)
      {
         switch (RemoveMode)
         {
            case ext_DisconnectMode.ext_dm_HostShutdown:
            case ext_DisconnectMode.ext_dm_UserClosed:

               windowVisibilityEvents.WindowShowing -= new _dispWindowVisibilityEvents_WindowShowingEventHandler(
                  windowVisibilityEvents_WindowShowing);
               windowVisibilityEvents.WindowHiding -= new _dispWindowVisibilityEvents_WindowHidingEventHandler(
                  windowVisibilityEvents_WindowHiding);
               windowVisibilityEvents = null;

               break;
         }
      }

      public void OnBeginShutdown(ref System.Array custom)
      {
      }

      public void OnAddInsUpdate(ref System.Array custom)
      {
      }

      private void windowVisibilityEvents_WindowShowing(EnvDTE.Window window)
      {
         if (window.Type != vsWindowType.vsWindowTypeDocument)
         {
            System.Windows.Forms.MessageBox.Show("Showing toolwindow of kind " + window.ObjectKind.ToString() + " and caption '" + 
               window.Caption + "'");
         }
      }

      private void windowVisibilityEvents_WindowHiding(EnvDTE.Window window)
      {
         if (window.Type != vsWindowType.vsWindowTypeDocument)
         {
            System.Windows.Forms.MessageBox.Show("Hiding toolwindow of kind " + window.ObjectKind.ToString() + " and caption '" + 
               window.Caption + "'");
         }
      }

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

Public Class Connect
   Implements Extensibility.IDTExtensibility2

   Private applicationObject As EnvDTE.DTE
   Private addInInstance As EnvDTE.AddIn
   Private WithEvents windowVisibilityEvents As EnvDTE80.WindowVisibilityEvents

   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

         applicationObject = CType(application, EnvDTE.DTE)
         addInInstance = CType(addInInst, EnvDTE.AddIn)

         Select Case connectMode

            Case ext_ConnectMode.ext_cm_UISetup

               ' Do nothing

            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
               ' Visual Studio will call OnStartupComplete when fully initialized

            Case ext_ConnectMode.ext_cm_AfterStartup

               ' The add-in was loaded by hand after startup using the Add-In Manager
               ' Initialize it in the same way that when is loaded on startup
               InitializeAddIn()

         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

      InitializeAddIn()

   End Sub

   Public Sub InitializeAddIn()

      Dim events2 As EnvDTE80.Events2

      events2 = DirectCast(applicationObject.Events, EnvDTE80.Events2)

      windowVisibilityEvents = events2.WindowVisibilityEvents()

   End Sub

   Public Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnDisconnection

      Select Case RemoveMode

         Case ext_DisconnectMode.ext_dm_HostShutdown, ext_DisconnectMode.ext_dm_UserClosed

            windowVisibilityEvents = Nothing

      End Select

   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

   Private Sub windowVisibilityEvents_WindowShowing(ByVal window As EnvDTE.Window) Handles windowVisibilityEvents.WindowShowing

      If window.Type <> vsWindowType.vsWindowTypeDocument Then

         System.Windows.Forms.MessageBox.Show("Showing toolwindow of kind " & window.ObjectKind.ToString() & " and caption '" & _
            window.Caption & "'")

      End If

   End Sub

   Private Sub windowVisibilityEvents_WindowHiding(ByVal window As EnvDTE.Window) Handles windowVisibilityEvents.WindowHiding

      If window.Type <> vsWindowType.vsWindowTypeDocument Then

         System.Windows.Forms.MessageBox.Show("Hiding toolwindow of kind " & window.ObjectKind.ToString() & _
            " and caption '" & window.Caption & "'")

      End If

   End Sub

End Class

Related articles



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


Top