5

I want to implement something that programmatically changes the background of the text when provided with a documentline.(Something that looks very similar to a block selection of a text. I'm going to be using this for debug breakpoints of an IDE I'm designing). I don't want to have to use selection as it causes the textbox to scroll.

I think I need to make use of DocumentColorizingTransformer but I'm not 100% sure how to go about this.

public class ColorizeAvalonEdit : ICSharpCode.AvalonEdit.Rendering.DocumentColorizingTransformer
    {
        protected override void ColorizeLine(ICSharpCode.AvalonEdit.Document.DocumentLine line)
        {
            int lineStartOffset = line.Offset;
            string text = CurrentContext.Document.GetText(line);
            int start = 0;
            int index;
            if (line.LineNumber == LogicSimViewCodeWPFCtrl.currentLine)
            {
                while ((index = text.IndexOf(text, start)) >= 0)
                {
                    base.ChangeLinePart(
                        lineStartOffset + index, // startOffset
                        lineStartOffset + index + text.Length, // endOffset
                        (VisualLineElement element) =>
                        {
                            element.TextRunProperties.SetBackgroundBrush(Brushes.Red);

                        });
                    start = index + 1; // search for next occurrence
                }
            }
        }
    }

currentLine is the portion that will be highlighted.

The above code does work properly.. only problem is if the currentLine ever changes while I am viewing that line, it doesn't highlight the updated line until I scroll to another portion of the document (hiding the updated line), and come back to the updated line.

Also, how do I make the line numbers start from zero?

TtT23
  • 6,876
  • 34
  • 103
  • 174

3 Answers3

3

Since it was their creation, I peeked at SharpDevelop's source and how they did it.

They defined a bookmark type (BreakpointBookmark) and added bookmark to the line. bookmark itself sets the color of the line in CreateMarker method. It is strange that it is not possible to configure colors of the break-point in SharpDevelop.

Hope it helps.

    protected override ITextMarker CreateMarker(ITextMarkerService markerService)
    {
        IDocumentLine line = this.Document.GetLine(this.LineNumber);
        ITextMarker marker = markerService.Create(line.Offset, line.Length);
        marker.BackgroundColor = Color.FromRgb(180, 38, 38);
        marker.ForegroundColor = Colors.White;
        return marker;
    }
Erdogan Kurtur
  • 3,630
  • 21
  • 39
  • 1
    Appreciate the answer. However, after taking a look at how sharpdevelop handles this problem, I think that having to add a lot of classes, interfaces on top of making substantial changes to the code to implement what seems to be a simple feature doesn't sound feasible. – TtT23 Aug 17 '12 at 04:19
  • In deep down, SharpDevelop does the same what you do. It creates breakpoints as bookmark markers which are TextSegments. In TextMarkerService.ColorizeLine, it find markers (segments) of its own and colorizes whole line. What you need to create just one class MyMarker:TextSegment and keep it in a variable of type. TextSegmentCollection. In ColorizeLine, copy from TextMarkerService.ColorizeLine and you are done. – Erdogan Kurtur Aug 17 '12 at 07:48
  • For line numbers, you have to edit LineNumberMargin.OnRender and build AvalonEdit. – Erdogan Kurtur Aug 17 '12 at 07:53
  • But the problem is not that I cannot set highlight on the text. The problem is that the highlighted portion of the text isn't properly invalidating despite the invalidation calls I am making in the application. I will try this solution anyways to see what I get but I honestly feel this is an overkill – TtT23 Aug 20 '12 at 06:27
3

I found the answer

TxtEditCodeViewer.TextArea.TextView.Redraw();
TtT23
  • 6,876
  • 34
  • 103
  • 174
0

Isn't this a duplicate of this question?

However it looks like you should call InvalidateArrange() on the editor or InvalidateVisual() on each changed visual.

Community
  • 1
  • 1
Louis Somers
  • 2,560
  • 3
  • 27
  • 57
  • I've called those. No luck. More specifically: TxtEditCodeViewer.TextArea.TextView.InvalidateVisual(); TxtEditCodeViewer.TextArea.TextView.InvalidateArrange(); TxtEditCodeViewer.TextArea.TextView.InvalidateMeasure(); – TtT23 Aug 20 '12 at 00:55