How to check that the tool window in my VS 2017 extension for is hidden

993 Views Asked by At

I'm developing an extension for Visual Studio 2017 which contains custom "toolwindow". This "toolwindow" contains WPF control with a view model subscribed to the Workspace.WorkspaceChanged and EnvDTE.DTE.Events.WindowEvents.WindowActivated events.

I know that when the "toolwindow" is closed by user it's not actually destroyed but rather "hidden". However, it still reacts to my events.

So, I want to know answers for two questions:

  1. How to check that the tool window is hidden?
  2. Can I "close" the tool window so it will be destroyed?

EDIT: The code to create tool window:

protected virtual TWindow OpenToolWindow()
{
        ThreadHelper.ThrowIfNotOnUIThread();

        // Get the instance number 0 of this tool window. This window is single instance so this instance
        // is actually the only one.
        // The last flag is set to true so that if the tool window does not exists it will be created.
        ToolWindowPane window = Package.FindToolWindow(typeof(TWindow), id: 0, create: true);

        if (window?.Frame == null)
        {
            throw new NotSupportedException("Cannot create tool window");
        }

        IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame;
        Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());
        return window as TWindow;
}
2

There are 2 best solutions below

2
On BEST ANSWER

To detect when a toolwindow is closed, you can inherit it from IVsWindowFrameNotify3 and in the OnShow method check for fShow == (int)__FRAMESHOW.FRAMESHOW_WinClosed.

0
On

Just to add to @Sergey Vlasov's answer - I found a second method to be notified if window is hidden/shown. Here's the code from my WPF control view model.

EnvDTE.DTE dte = MyVSPackage.Instance.GetService<EnvDTE.DTE>();

// _visibilityEvents is a private field. 
// There is a recommendation to store VS events objects in a field 
// to prevent them from being GCed
_visibilityEvents = (dte?.Events as EnvDTE80.Events2)?.WindowVisibilityEvents;

if (_visibilityEvents != null)
{
    _visibilityEvents.WindowShowing += VisibilityEvents_WindowShowing;
    _visibilityEvents.WindowHiding += VisibilityEvents_WindowHiding;
}