Developers working with Visual Studio on a project of significant size understand how cluttered the Solution Explorer becomes after a few hours of working. They click too many of those little minus signs — a repetitive task that no developer enjoys. Eventually they decide to ease their discomfort and search Google for a better solution. Luckily, a number of individuals have posted solutions for this task, gracefully solving the problem by creating macros assigned to specific key strokes.
Searching Google for ‘collapse solution explorer’ reveals many, many solutions. I found that two basic macros exist: 1) a quick collapse and 2) complete collapse. The quick version collapses all currently open nodes in the solution tree. The process is fast (2-ish seconds) and the screen looks nice and organized.
There is one problem with the quick collapse which leaves trouble lurking. If nodes of the tree were expanded but then hidden by collapsing the parent node, those expanded nodes further down the tree structure will not be collapsed. This occurs because the macro only collapses the children of a node if the parent node is expanded.
This problem with quick collapse is addressed by the second macro: complete collapse. The complete collapse iterates through the entire tree regardless of the parent node’s expanded/collapsed status. This forces every node of the tree to be collapsed. It is a thorough process and guarantees that the solution explorer will be in perfect order however, it is a lengthy process for projects of significant size (15-ish seconds).
The code I provide below combines these two macros into one module. You can assign each a separate keystroke and have the power of both at your fingertips. Use the quick collapse as everyday cleanup; use the complete collapse for those times when the solution explorer has become unruly.
I also added a bit of functionality to the quick collapse. I usually collapse the solution explorer because I want to declutter my work space before diving into a task. That often means that I have a number of files open that I am no longer working on. To address this, I provide two additional macros that will close all open files before executing the quick collapse. The first macro closes all files except the active window. The second macro closes all files including the active window. The files are automatically saved before closing.
Using Tools > Options > Environment > Keyboard, you can assign each macro a keyboard shortcut. I prefer the following:
| Shortcut Key | Macro Assigned |
|---|---|
| Alt+\ | Quick Collapse |
| Ctrl+Alt+\ | Complete Collapse |
| Alt+/ | Quick Collapse – close all documents except active |
| Ctrl+Alt+/ | Quick Collapse – close all documents including active |
Here is a link to step-by-step instructions for creating macros and setting the keyboard shortcuts. Here is a link to step-by-step instructions for adding macros as a toolbar button.
The Macros
Download the CollapseSolutionExplorer macro file here or copy and paste from below.
Imports EnvDTE
Imports System.Diagnostics
Public Module CollapseSolutionExplorer
Sub QuickCollapseAndClose()
CloseAllWindows(False)
DoCollapse(True)
End Sub
Sub QuickCollapseAndCloseKeepActive()
CloseAllWindows(True)
DoCollapse(True)
End Sub
Sub QuickCollapse()
DoCollapse(True)
End Sub
Sub CompleteCollapse()
DoCollapse(False)
End Sub
Private Sub DoCollapse(ByVal quick As Boolean)
' Get the the Solution Explorer tree
Dim UIHSolutionExplorer As UIHierarchy
UIHSolutionExplorer = DTE.Windows.Item(Constants.vsext_wk_SProjectWindow).Object()
' Check if there is an open solution
If (UIHSolutionExplorer.UIHierarchyItems.Count = 0) Then
Return
End If
' Get the top node (the name of the solution)
Dim UIHSolutionRootNode As UIHierarchyItem
UIHSolutionRootNode = UIHSolutionExplorer.UIHierarchyItems.Item(1)
' Hide the Solution Explorer to prevent multiple screen paints
DTE.StatusBar.Text = "Solution Explorer hidden... it will return..."
Dim activeWindow As EnvDTE.Window
activeWindow = UIHSolutionExplorer.DTE.ActiveWindow
DTE.Windows.Item(Constants.vsext_wk_SProjectWindow).Visible = False
' Select the solution (top) node so that the open document isn't automatically expanded
UIHSolutionRootNode.Select(vsUISelectionType.vsUISelectionTypeSelect)
' Collapse each project node
Dim UIHItem As UIHierarchyItem
For Each UIHItem In UIHSolutionRootNode.UIHierarchyItems
' the first-level is always collapsed, regardless of quick or not
' this is a nice feature that makes the quick collapse more useful
Collapse(UIHItem, quick)
Next
' Bring back the Solution Explorer
DTE.Windows.Item(Constants.vsext_wk_SProjectWindow).Visible = True
' Clear the status bar
DTE.StatusBar.Clear()
DTE.StatusBar.Progress(False)
End Sub
Private Sub Collapse(ByVal item As UIHierarchyItem, ByVal quick As Boolean)
'recursive function
For Each eitem As UIHierarchyItem In item.UIHierarchyItems
If ((quick = True) And (eitem.UIHierarchyItems.Expanded = True)) Or (quick = False) Then
If eitem.UIHierarchyItems.Count > 0 Then
DTE.StatusBar.Text = "Solution Explorer hidden... it will return... Collapsing " & item.Name
Collapse(eitem, quick) ' recursion here
End If
End If
Next
item.UIHierarchyItems.Expanded = False
End Sub
Private Sub CloseAllWindows(ByVal KeepCurrentOpen As Boolean)
On Error Resume Next
Dim i As Integer
Dim sCurrWin As String = DTE.ActiveDocument.Name
With DTE
For i = .Documents.Count To 1 Step -1
If .Documents.Item(i).Name <> sCurrWin Or KeepCurrentOpen = False Then
.Documents.Item(i).Close(vsSaveChanges.vsSaveChangesYes)
End If
Next
End With
End Sub
End Module