如何在Visual Studio扩展中以编程方式折叠源代码块
实现Visual Studio扩展中自动折叠插入的#region区域
核心思路
要折叠刚插入的#region,需要借助Visual Studio文本编辑器的结构导航器(ITextStructureNavigator)定位目标区域,再通过IWpfTextView的折叠API完成操作。以下是具体实现步骤:
1. 获取当前活动的文本视图
首先拿到当前可见编辑器对应的IWpfTextView实例,这是操作编辑器的核心入口:
using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.TextManager.Interop; private IWpfTextView GetCurrentActiveTextView() { var textManager = (IVsTextManager)Package.GetGlobalService(typeof(SVsTextManager)); if (textManager == null) return null; // 获取活动视图(第二个参数为null表示当前活动文档) textManager.GetActiveView(1, null, out var vsTextView); return vsTextView as IWpfTextView; }
2. 定位插入的#region区域
假设你在插入#region和#endregion时已经记录了它们在文本缓冲区中的起始和结束字符偏移量(比如regionStart和regionEnd),直接构造对应的Span:
// 构造#region到#endregion的完整文本范围 var targetSpan = new Span(regionStart, regionEnd - regionStart);
如果未记录位置,也可以通过文本分类器遍历文档匹配刚插入的#region块,但记录位置的方式更高效。
3. 获取可折叠区域并执行折叠
通过ITextStructureNavigator获取目标区域内的可折叠节点,调用折叠方法完成操作:
using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Structure; public void FoldInsertedRegion(int regionStart, int regionEnd) { var textView = GetCurrentActiveTextView(); if (textView == null) return; var navigator = textView.GetTextStructureNavigator(); if (navigator == null) return; var targetSpan = new Span(regionStart, regionEnd - regionStart); var collapsibleRegions = navigator.GetCollapsibleRegions(targetSpan); // 遍历并折叠匹配的#region区域 foreach (var region in collapsibleRegions) { if (region.IsCollapsible) { textView.Collapse(region.Extent); } } }
4. 关键注意事项
- 等待文本结构解析完成:插入代码后,IDE需要时间解析新的代码结构,建议在文本变更完成后延迟执行折叠操作:
textView.TextBuffer.Changed += (s, e) => { if (e.Changes.Any(change => change.NewText.Contains("#region"))) { // 延迟执行确保结构解析完成 textView.Dispatcher.BeginInvoke(new Action(() => FoldInsertedRegion(regionStart, regionEnd))); } }; - 引用必要程序集:确保扩展项目引用
Microsoft.VisualStudio.Text.UI、Microsoft.VisualStudio.Text.Logic、Microsoft.VisualStudio.Shell等相关程序集。
内容的提问来源于stack exchange,提问作者FrankS
相关产品推荐
相关产品推荐

