Question

I am wanting to highlight all instances of the selected (highlighted) text in AvalonEdit. VS2010 does this and it's a handy feature. I understand I need to implement a DocumentColorizingTransformer as per the code below but don't know how to obtain the selected text from the document. Selection information isn't available in the "CurrentContext".

The code below finds all instances of "AvalonEdit". How can I find all instances of the selected (highlighted) text.

public class ColorizeAvalonEdit : DocumentColorizingTransformer
{
protected override void ColorizeLine(DocumentLine line)
{
    int lineStartOffset = line.Offset;
    string text = CurrentContext.Document.GetText(line);
    int start = 0;
    int index;
    while ((index = text.IndexOf("AvalonEdit", start)) >= 0) {
        base.ChangeLinePart(
            lineStartOffset + index, // startOffset
            lineStartOffset + index + 10, // endOffset
            (VisualLineElement element) => {
                // This lambda gets called once for every VisualLineElement
                // between the specified offsets.
                Typeface tf = element.TextRunProperties.Typeface;
                // Replace the typeface with a modified version of
                // the same typeface
                element.TextRunProperties.SetTypeface(new Typeface(
                    tf.FontFamily,
                    FontStyles.Italic,
                    FontWeights.Bold,
                    tf.Stretch
                ));
            });
        start = index + 1; // search for next occurrence
}   }   }
Was it helpful?

Solution

The current text selection is available on the TextEditor so you could use that from your ColorizeAvalonEdit class.

public class ColorizeAvalonEdit : DocumentColorizingTransformer
{
    protected override void ColorizeLine(DocumentLine line)
    {
        int lineStartOffset = line.Offset;
        string text = CurrentContext.Document.GetText(line);
        int start = 0;
        int index;
        while ((index = text.IndexOf("AvalonEdit", start)) >= 0) {
            base.ChangeLinePart(
                lineStartOffset + index, // startOffset
                lineStartOffset + index + 10, // endOffset
                (VisualLineElement element) => {
                    // This lambda gets called once for every VisualLineElement
                    // between the specified offsets.
                    Typeface tf = element.TextRunProperties.Typeface;
                    // Replace the typeface with a modified version of
                    // the same typeface
                    element.TextRunProperties.SetTypeface(new Typeface(
                        tf.FontFamily,
                        FontStyles.Italic,
                        FontWeights.Bold,
                        tf.Stretch
                    ));
                });
            start = index + 1; // search for next occurrence
        }
    }
}

However this is not enough to get all the selected text to be bold and italic on every line since only the line being modified will be updated. In order to get all the selected text to be bold and italic I had to refresh the text editor when the selection changed.

    textEditor.TextArea.TextView.LineTransformers.Add(new ColorizeAvalonEdit(textEditor));
    textEditor.TextArea.SelectionChanged += textEditor_TextArea_SelectionChanged;

    void textEditor_TextArea_SelectionChanged(object sender, EventArgs e)
    {
        this.textEditor.TextArea.TextView.Redraw();
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top