views:

348

answers:

1

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.

+5  A: 

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.

Bob King
So no out of the box Annotations like DocumentViewer can be made available to controls, you think?Thanks for that explanation and code snippet, Let me try to run this and see if I can get it.
Vin
I can't think of away to use existing Annotations out of the box, because you'd need something that works with UIElement, since that's (and it's subclasses) almost exclusively what you deal with in regular UI development. There may some third party project, but I'm unaware of it.
Bob King