I've recently developed a drawing component for my company, featuring a Canvas on which you can draw certain shapes using click-and-drag. For each shape, I placed two adorners on its AdornerLayer: One for increased hit detection (basically a transparent rectangle that would exceed the shape's boundaries by a few pixels), and another for resizing (four Thumb controls on the corners).
But, I ran into many problems when implementing some of the features of the component, all adorner related.
They captured all preview events, since they were in another visual tree than the Canvas itself, that was unexpected, but I found a workaround, even if I did not like it that much. Using an AdornerDecorator did not solve this issue, a selection adorner as I implemented is a black hole for preview events.
When I implemented z-index manipulation of shapes on the Canvas (send to back, bring to front, etc), it worked fine using Panel.SetZIndex, as you'd expect. But, the adorners are in another visual tree! so they were not affected and the selection adorners were STILL on top of all other shapes, even if those shapes were on top of the one the selection adorner was detecting hits for. For example: Shape1, SelectionAdorner1. Shape2, SelectionAdorner2. Shape1 is on top (added later to the canvas) of Shape2, so it's overlapping it. So a click on it will be detected by SelectionAdorner1. I manipulated the ZIndex to send it to back, now Shape2 is on top and overlaps Shape1. I click on top of Shape2, but the click is detected by SelectionAdorner1 instead of SelectionAdorner2. This was particularly annoying. So, apparently since Adorners are on another visual tree, they don't respect ZIndexes. I tried to solve it by creating a DataBinding (and also by manually setting) between the ZIndex of the shape and the ZIndex of its SelectionAdorner. But this did not solve the issue. Altering the ZIndex of Adorners did not affect the way they were displayed on screen, maybe I was missing something, but it shouldn't be really this hard, since Adorners are supposed to be made to make things easier. The only solution I could come up with was manually removing all adorners and add them again manually one by one, adding for last the one that was supposed to be on top. That was retarded, but it worked.
Next, Adorners don't respect ClipToBounds! I set ClipToBounds=true in the Canvas I was doing my drawing on, and it worked fine, but damn adorners would still work! The solution to this was relatively painless, I just added an AdornerDecorator on top of each Shape. Not an ideal solution IMO, but one that was simple enough.
Adorners not always react well to LayoutTransforms performed on their adorned elements. I have a Panel on top of the canvas which implements Zoom and Pan functionality. It used Animations to make zooming in and out more smooth. But using animations caused my Adorners to go ape! The first zoom they would simply ignore the resize and stay the same size and position, on the second zoom they would scale to the previous size of the adorned element. That did not make any sense! only solution I could find was to disable animations, which thankfully worked
I don't quite remember which other issues I had, but this was more than enough to mame me wonder about the usefulness of Adorners, and I'm seriously considering not using them in my next project, which is similar to the one I described.
So, can anyone tell me what could possibly be the pros of using these seemingly useful but incredibly annoying things?
Thanks.