I am trying to make a nice "drag and drop zone" in WPF that is displayed in the adorner layer when something is being dragged into the main application. The problem is that I do not get any events from my adorner, even though it according to documentation should receive all input events since it is in a higher z-order.
To debug my problem I created a really simple example where I have a user control with only a button in it. This user control is displayed in the adorner layer, but I cannot click the button. Why? What have I done wrong?
My adorner class is constructed like this:
public ShellOverlayAdorner(UIElement element, AdornerLayer adornerLayer)
:base(element)
{
_adornerLayer = adornerLayer;
_overlayView = new AdornedElement();
_overlayView.AllowDrop = true;
_adornerLayer.Add(this);
}
and is created in the main window by
private void Window_Loaded(object sender, RoutedEventArgs e)
{
adornerLayer = AdornerLayer.GetAdornerLayer(MyTopGridWithButtonInIt);
ShellOverlayAdorner shell = new ShellOverlayAdorner(MyTopGridWithButtonInIt, adornerLayer);
}
I do not get any events at all from my control, i.e. no mouse clicks, mouse over, button clicks. I cannot even click the button in the adorner layer. What have I done wrong?
I don't know if you already tried that: If you want the element added to react to events, I think that the element must be bound to the visual tree of the adorner. The way to do it is to use a VisualCollection, intitialized to the adorner itself, or at least, this way it seems to be working:
VisualCollection visualChildren;
FrameworkElement @object;
public CustomAdorner(UIElement adornedElement) :
base(adornedElement)
{
visualChildren = new VisualCollection(this);
@object = new Button {Content = "prova"};
visualChildren.Add(@object);
}
protected override Visual GetVisualChild(int index)
{
return visualChildren[index];
}
This way the events are correctly routed.
I just had the same issue. Following the advice from MSDN sorted it for me:
Adorners receive input events just like any other FrameworkElement. Because an adorner always has a higher z-order than the element it adorns, the adorner receives input events (such as Drop or MouseMove) that may be intended for the underlying adorned element. An adorner can listen for certain input events and pass these on to the underlying adorned element by re-raising the event.
To enable pass-through hit testing of elements under an adorner, set the hit test IsHitTestVisible property to false on the adorner.
i.e In the adorner itself, make sure IsHitTestVisible = false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With