The C# language offers the #region and #endregion statements as a means of code organization. Microsoft Visual Studio lets users visually collapse such regions to a single line, and automatically collapses all regions when a C# source code file is opened for the first time.
Unfortunately, this is the total extent of Visual Studio support for regions. The IDE does not otherwise distinguish between C# regions and other constructs with outlining support. Collapsing and expanding commands operate on all supported constructs within the scope of the command, not just regions. This is usually undesirable – who would want to collapse all for loops or XML comments, for example? There is an old MSDN Feedback item asking for dedicated #region support but Microsoft appears in no hurry to do anything about it.
On the other hand, one could write a Visual Studio macro that provides such functionality, and that’s exactly what Roland Weigelt did in 2003. In the comment section of the linked weblog, Andrew Eno posted a revised version that deals with nested regions. This version forms the basis for the code shown below.
Simply copy & paste the code below into a project called “RegionTools” within the Visual Studio Macros IDE. You can then assign each of the three macros a keyboard shortcut within the main IDE. The code is intended for Visual Studio 2010; change the indicated lines for Visual Studio 2008 (search for “VS2008”). Visual Studio 2012 does not support macros (in any edition) and therefore cannot run this code at all, sorry!
Known Issues: ToggleParentRegion does nothing if the cursor is at the end of a collapsed #region line. In that case, SelectLine inadvertently expands the region which is immediately re-collapsed by the following call to ToggleOutliningExpansion.
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports EnvDTE90a ' remove for VS2008
Imports EnvDTE100 ' remove for VS2008
Imports System.Diagnostics
' Macros for improving keyboard support for "#region ... #endregion"
' Original version written by Roland Weigelt, last modified 2003-08-14
' Original source: http://weblogs.asp.net/rweigelt/archive/2003/07/06/9741.aspx
' Includes changes by Andrew Eno, posted on 2003-10-08 at the same location
Public Module RegionTools
' Toggles the current region surrounding the cursor
Sub ToggleParentRegion()
DTE.SuppressUI = True
Dim objSelection As TextSelection = DTE.ActiveDocument.Selection
Dim objPosition As EnvDTE.TextPoint = objSelection.AnchorPoint
' select current line in case it contains a #region
objSelection.SelectLine()
Dim regionFound As Boolean = InStr(objSelection.Text.ToLower(), "#region") > 0 _
OrElse objSelection.FindText("#region", vsFindOptions.vsFindOptionsBackwards)
' clear previous line selection
objSelection.MoveToPoint(objPosition)
If regionFound Then
DTE.ExecuteCommand("Edit.ToggleOutliningExpansion")
objSelection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn)
End If
DTE.SuppressUI = False
End Sub
' Expands all regions in the current document
Sub ExpandAllRegions()
DTE.SuppressUI = True
Dim objSelection As TextSelection = DTE.ActiveDocument.Selection()
objSelection.StartOfDocument()
While objSelection.FindText("#region", vsFindOptions.vsFindOptionsMatchInHiddenText)
' do nothing since FindText automatically expands any found #region
End While
objSelection.StartOfDocument()
DTE.SuppressUI = False
End Sub
' Collapses all regions in the current document
Sub CollapseAllRegions()
ExpandAllRegions()
DTE.SuppressUI = True
Dim objSelection As TextSelection = DTE.ActiveDocument.Selection
objSelection.EndOfDocument()
' search backward to find innermost nested regions first
While objSelection.FindText("#region", vsFindOptions.vsFindOptionsBackwards)
DTE.ExecuteCommand("Edit.ToggleOutliningExpansion")
' objSelection.EndOfDocument() ' uncomment for VS2008
End While
objSelection.StartOfDocument()
DTE.SuppressUI = False
End Sub
End Module