Reputation: 612
I want to highlight all the occurrences of the selected word when the mouse is double clicked. This question Highlight all occurrences of selected word in AvalonEdit does answer how to do it with a Document Colorizer, but I am not sure how to pass the word in. Also, how do i trigger the recoloring with the mouse double click ?
Upvotes: 2
Views: 1002
Reputation: 71
If you want to highlight the words simply by changing the background color, there's one simple solution: Use an IBackgroundRenderer
To store the parts of the document that should be highlighted you can use a TextSegmentCollection<T>
. This collection stores TextSegment
instances, which you can then use in the IBackgroundRenderer.Draw
method implementation.
The Layer
property should return the layer on which the IBackgroundRenderer
renders. This can simply be KnownLayer.Selection
to render behind the selection.
The Draw
method can be implemented as follows:
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.AlignToMiddleOfPixels = true;
geoBuilder.CornerRadius = 3;
geoBuilder.AddSegment(textView, result);
Geometry geometry = geoBuilder.CreateGeometry();
if (geometry != null) {
drawingContext.DrawGeometry(markerBrush, markerPen, geometry);
}
}
A short explanation: First you have to check whether the VisualLines
are valid and if there are any. If there aren't, there's nothing to do, thus we exit.
Then you can calculate the visible range by using the start offset of the first visible document line and the end offset of the last visible document line. This should speed up the rendering process, because we only process what's currently visible.
FindOverlappingSegments
returns a list of all segments that overlap with the given range.
Then we use the BackgroundGeometryBuilder
, a helper class, to create a nice-looking geometry for the highlight. This is also used for the currently selected text in AvalonEdit.
To add it to the TextEditor
use: textEditor.TextArea.TextView.BackgroundRenderers.Add(renderer);
If you expose the results as property you can then use: renderer.Results.Add(result);
To refresh the screen you can use textEditor.TextArea.TextView.InvalidateLayer(KnownLayer.Selection);
if it is not done automatically.
Upvotes: 4