ssarangi
ssarangi

Reputation: 612

Highlight all occurrences of word in avalonedit

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

Answers (1)

Siegfried
Siegfried

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

Related Questions