Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to allow the user to add annotations to UI controls in WPF?

Tags:

WPF document viewing controls that support annotations include FlowDocumentReader and FlowDocumentScrollViewer, as well as controls derived from DocumentViewerBase such as DocumentViewer and FlowDocumentPageViewer.

The in-built Annotations support for Document based controls is awesome in WPF

I was wondering how would it be possible to add the functionality to WPF common controls like Button, TextBox, ListBox items etc. Idea is to allow the user to pass on some comments on the UI screen, to another user.

First thing that comes to mind is to inherit from the DocumentViewerBase and create your own custom controls. I am not sure about how it would work out. What if non-custom controls need to be annotated?

Has any one worked or seen this kind of feature?

Any directions would be helpful.

like image 437
Vin Avatar asked Feb 03 '09 14:02

Vin


1 Answers

Hmmm. I would probably do this with an adorner:

Imports System.Windows
Imports System.Windows.Documents
Imports System.Windows.Media

Public Class Annotation
    Inherits Adorner

    Private _fill As Brush
    Private _pen As Pen
    Private _text As FormattedText
    Private _annotationText as String

    Public Sub New(ByVal adornedElement As UIElement, ByVal annotationText as String)
        MyBase.New(adornedElement)
        _annotationText = annotationText
        _fill = New SolidColorBrush(Color.FromArgb(&H33, &HB0, &HC4, &HDE))
        _fill.Freeze()
        _pen = New Pen(Brushes.LightSteelBlue, 3.0)
        _pen.Freeze()
        _text = New FormattedText(_annotationText, Globalization.CultureInfo.InvariantCulture, FlowDirection.LeftToRight, New Typeface("Verdana"), 11.0, Brushes.Black)
        Me.IsHitTestVisible = False
    End Sub

    Protected Overrides Sub OnRender(ByVal drawingContext As DrawingContext)
        MyBase.OnRender(drawingContext)
        Dim adornedRect As New Rect(MyBase.AdornedElement.RenderSize)
        drawingContext.DrawRectangle(_fill, _pen, adornedRect)
        drawingContext.DrawText(_text, New Point(0,0))
    End Sub

End Class

And then you would use it by:

Private Sub AddAnnotation(ByVal uie As UIElement, ByVal annotationText as String)
    Dim annotation = New Annotation(uie)
    Dim adornerLayer = AdornerLayer.GetAdornerLayer(uie, annotationText)
    adornerLayer.Add(annotation)
End Sub

I will leave you to adjust the position and the actual appearance of the annotation, but you get the idea. This will work for any UIElement, including custom controls.

This was an off the cuff answer based on some other work I'd done with Adorners. Above code may or may not compile. I did not provide a way to edit annotations, but you can do so easily by removing the "Me.IsHitTestVisible = False" line and handling MouseUp events in the adorner.

like image 190
Bob King Avatar answered Oct 12 '22 12:10

Bob King