Rendering text in the adorner layer

This blog post shows one way to render text in the adorner layer.  I created an adorner class named TextBlockAdorner, which allows you to render a TextBlock over an element by placing it into the adorner layer.  If you don’t know what the adorner layer is yet, you might want to read this article.

Christian Graus recently posted a question to the WPF Forum asking how to render text in a Viewbox, but without having the text size be affected by the scaling of the Viewbox.  The solution I came up with is shown below.

Suppose that this is the Viewbox which we want to place text over, and have that text not be scaled or modified:

TextBlockAdorner Demo (xaml)

In the code-behind for the Window which contains the Viewbox, we can use my TextBlockAdorner to specify what text to display over the Viewbox.

TextBlockAdorner Demo (usage)

After we’re done with that, the UI looks like this:

 TextBlockAdorner Demo (screenshot)

As you can see above, the text in the ViewBox is scaled down to a smaller size than the “natural” font size in the Window.  The adorner text uses the “natural” font size because it is not affected by the Viewbox.

The demo app does not provide a clean way of repositioning the adorner text, so that is an exercise left up to the reader.  There are numerous examples on the Web which show how to use a TranslateTransform to move the contents of an adorner, such as this article and my ListViewDragDropManager’s DragAdorner class.

Download the demo project here:  TextBlockAdorner Demo (demo project)  Be sure to change the file extension from .DOC to .ZIP and then decompress it.

5 Responses to Rendering text in the adorner layer

  1. Christian Graus says:

    Hey, Josh, I *really* appreciate you do this for me, but I’m still stuck. My code drags out a textbox, then I enter the text, and finally, I create the textblock which copies the RenderTransform from the TextBox, to position it properly. This obvioulsy no longer works. I looked at the articles you linked to, and copied the code to set the position of the text from your CP article.

    My issue is twofold. I have a Grid in my tool class, the textblock needs to be discoverable from that grid, and it needs to scale itself to the grid. I believe I need to create an adorner decorator in code ( as the textblock is created in code ) and to make the decorator a child of the grid. I’ve done this:

    AdornerDecorator decorator = new AdornerDecorator();
    decorator.Child = label;

    But of course, the label is already a child of the adorner. So, I tried putting the decorator in the adorner, but no luck. Basically, it’s doing one thing I really need ( if I resize the frame, the label moves so it keeps it’s position ), but not the other, I cannot work out how to position the label relative to the grid, which I guess means I need to work out how to get the co-ordinates of the grid on the screen. I tried this

    _grid.PointToScreen(_grid.RenderTransformOrigin);

    and adding it to my initial offset, but the label is still jumping all over the place.

    Again, I really appreciate your help, I don’t want you to think I *expect* it, but if you are able to point me in the right direction here, I have co-ordinates which, if put in a translate transform for the control added to the grid, position the text properly. I cannot work out how to use those co-ordinates to position the text when it’s in an adorner. I’m also assuming I can make this class you provided templated, and use it for a textbox as well, is that right ?

  2. […] an Image in a Viewbox In my previous blog post we reviewed a custom adorner which allowed us to place a TextBlock into the adorner layer of a […]

  3. Josh Smith says:

    Christian,

    I came up with a solution for what you described, here: https://joshsmithonwpf.wordpress.com/2007/08/26/annotating-an-image-in-a-viewbox/

    I normally don’t go this far out of my way to help someone out, but I found this problem very interesting. 🙂

    Josh

  4. Logan says:

    The adorners article link is broken. Also, quit setting all of your links to target=_blank. It’s annoying. I know full well how to open a link in a new tab if that is what I wanted. Perhaps you feel as though your site is more important than everyone else’s, and therefore I would never want to accidentally navigate away from yours. 😛

  5. Josh Smith says:

    Thanks for letting me know about the broken link, Logan. As to your other “feedback,” it’s my blog and I’ll create the links however I please. If you don’t like it, don’t click on them.

    Josh