如何用IBackgroundRenderer实现AvalonEdit选中词全高亮?
AvalonEdit实现选中单词全文档高亮(解决默认高亮冲突问题)
作为C#新手,在开发嵌入AvalonEdit的代码编辑器时,需要实现选中单词全文档高亮功能。最初使用DocumentColorizingTransformer实现,但出现了与默认语法高亮冲突、视觉显示有瑕疵的问题。
了解到可以通过IBackgroundRenderer类来实现该功能,但现有资料仅提供Draw方法的结构框架,缺少完整实现细节,尤其是不清楚如何传递需要高亮的匹配词。最终自行解决问题,以下是完整可运行代码:
1. 高亮渲染器核心实现
using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Rendering; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows; using System.Windows.Media; namespace SVGRecolorTool { public class SearchResult : TextSegment { /// <summary>搜索结果对应的正则匹配项</summary> public Match Match { get; } /// <summary>从匹配项构造搜索结果</summary> public SearchResult(Match match) { this.StartOffset = match.Index; this.Length = match.Length; this.Match = match; } } public class HighlightSelectedWordBackgroundRenderer : IBackgroundRenderer { private TextEditor _editor; TextSegmentCollection<SearchResult> currentResults = new TextSegmentCollection<SearchResult>(); public HighlightSelectedWordBackgroundRenderer(TextEditor editor) { _editor = editor; Background = new SolidColorBrush(Color.FromArgb(90, 255, 255, 255)); Background.Freeze(); } public KnownLayer Layer { get { return KnownLayer.Caret; } } public void Draw(TextView textView, DrawingContext drawingContext) { if (!textView.VisualLinesValid) return; var visualLines = textView.VisualLines; if (visualLines.Count == 0) return; int viewStart = visualLines.First().FirstDocumentLine.Offset; int viewEnd = visualLines.Last().LastDocumentLine.EndOffset; foreach (TextSegment result in currentResults.FindOverlappingSegments(viewStart, viewEnd - viewStart)) { BackgroundGeometryBuilder geoBuilder = new BackgroundGeometryBuilder(); geoBuilder.AlignToWholePixels = true; geoBuilder.CornerRadius = 0; geoBuilder.AddSegment(textView, result); Geometry geometry = geoBuilder.CreateGeometry(); if (geometry != null) { drawingContext.DrawGeometry(Background, null, geometry); } } } public TextSegmentCollection<SearchResult> CurrentResults { get { return currentResults; } } public Brush Background { get; set; } } }
2. 初始化渲染器
// 初始化高亮渲染器并绑定到编辑器 _renderer = new HighlightSelectedWordBackgroundRenderer(txtSvgSource); txtSvgSource.TextArea.TextView.BackgroundRenderers.Add(_renderer); // 监听选择变更事件触发高亮 txtSvgSource.TextArea.SelectionChanged += HighlightSelection;
3. 选择变更处理逻辑
private void HighlightSelection(object sender, EventArgs e) { _renderer.CurrentResults.Clear(); // 仅处理长度大于2的选中文本,避免误触发 if(txtSvgSource.SelectedText.Length > 2) { // 使用单词边界正则,确保匹配完整单词而非子串 string pattern = @"\b" + txtSvgSource.SelectedText + @"\b"; Regex rg = new Regex(pattern); MatchCollection matchedSelections = rg.Matches(txtSvgSource.Text); // 匹配数大于1时添加高亮项 if (matchedSelections.Count > 1) { foreach (Match result in matchedSelections) { _renderer.CurrentResults.Add(new SearchResult(result)); } } else { _renderer.CurrentResults.Clear(); } } else { _renderer.CurrentResults.Clear(); } // 刷新高亮层,确保视觉更新 txtSvgSource.TextArea.TextView.InvalidateLayer(KnownLayer.Selection); }
内容的提问来源于stack exchange,提问作者fmotion1
相关产品推荐
相关产品推荐

