The C# language offers the
#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?
One could write a Visual Studio macro that provides such functionality, though, 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 (sadly no longer accessible since a blog software update seems to have stripped out all code from comments). 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”). Please note that Visual Studio 2012 and later don’t 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
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/9741 ' 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