RichTextBox for WPF | ComponentOne
Working with WPF RichTextBox / Painters
In This Topic
    Painters
    In This Topic

    Painters are a way of extending C1RichTextBox by displaying UIElements in the same canvas where C1RichTextBox displays text. This allows more general extensions than style overrides, but might be harder to use. Painters are used internally by C1RichTextBox to display the selection.

    A painter is an implementation of the IRichTextPainter interface. This interface has two methods, IRichTextPainter.Paint and IRichTextPainter.PaintInline, which are called at different stages of C1RichTextBox's painting pass. Each method receives a C1PaintingContext object that is used to check the viewport being painted, and has the methods that are used for painting custom UIElements.

    IRichTextPainter.Paint is called each time the entire screen is repainted. Note that each time this method is called, all UIElements must be painted by calling C1PaintingContext.Paint, otherwise they will be removed. Passing the same UIElement each time is more efficient, as it is not removed from the visual tree.

    IRichTextPainter.PaintInline is called for each C1Line that is painted. This method allows finer control over the layer where custom UIElements are painted. For instance, it is possible to paint above the text background, but below the text itself. It has the same rule as IRichTextPainter.Paint. All UIElements must be painted by calling C1PaintingContext.PaintInline, otherwise they will be removed.

    The Annotations sample uses painters to display sticky notes. Here is the implementation:

    Visual Basic
    Copy Code
    Class StickyPainter
        Implements IRichTextPainter
        Private _stickies As List(Of StickyNote)
        Public Sub New(stickies As List(Of StickyNote))
            _stickies = stickies
        End Sub
        Public Sub Paint(context As C1PaintingContext)
            For Each sticky As var In _stickies
                Dim rect = context.ViewManager.GetRectFromPosition(sticky.Range.Start)
                context.Paint(Math.Round(rect.X), Math.Round(rect.Bottom), False, sticky)
            Next
        End Sub
        Public Sub PaintInline(context As C1PaintingContext, line As C1Line)
        End Sub
        Public Event PainterChanged As EventHandler(Of RichTextPainterChangeEventArgs)
    End Class
    

    C#
    Copy Code
    class StickyPainter : IRichTextPainter
    {
        List<StickyNote> _stickies;
        public StickyPainter(List<StickyNote> stickies)
        {
            _stickies = stickies;
        }
        public void Paint(C1PaintingContext context)
        {
            foreach (var sticky in _stickies)
            {
                var rect = context.ViewManager.GetRectFromPosition(sticky.Range.Start);
                context.Paint(Math.Round(rect.X), Math.Round(rect.Bottom), false, sticky);
            }
        }
        public void PaintInline(C1PaintingContext context, C1Line line)
        {
        }
        public event EventHandler<RichTextPainterChangeEventArgs> PainterChanged;
    }
    

    StickyPainter only uses the C1PaintingContext.Paint method. For each sticky note it just gets the coordinates inside document and then calls C1PaintingContext.Paint. Note that these are document coordinates; they are independent of paging, scrolling and zooming.