How to fire event under Adorner Layer

1.4k views Asked by At

I want to click a Button under Adorner Layer. Off course, In visual tree, Adorner is different branch from controls. Not able to handle PreviewMouseDown

What to do to fire events under adorner layer?

xaml is below.

<Canvas Name="_canvas" Width="100" Height="100">
    <Button Name="_btn" Width="120" Height="120"/>
</Canvas>

codebehind is below.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Loaded += delegate { AdornerLayer.GetAdornerLayer(_canvas).Add(new GrayAdorner(_canvas)); };

        _btn.Click += (sender, e) => MessageBox.Show("Mouse Click is working.");
    }
}

public class GrayAdorner : Adorner
{
    public GrayAdorner(UIElement element)
        : base(element) { }

    protected override void OnRender(DrawingContext drawingContext)
    {
        drawingContext.DrawRectangle(Brushes.Gray, null, new Rect(new Point(0, 0), DesiredSize));
        base.OnRender(drawingContext);
    }
}
2

There are 2 answers

1
sjw On BEST ANSWER

If you don't need the Adorner to be hit testable, set the IsHitTestVisible property of the GrayAdorner to false. Mouse events will ignore the Adorner and pass through to the Button underneath.

0
user947737 On

Try this for an Adorner with a child Control (that need to be IsHitTestVisible = True:

private void AdornerChildMouseDown(object sender, MouseButtonEventArgs e)
    {
        Adorner parentAdorner = VisualTreeHelper.GetParent(sender as DependencyObject) as Adorner;

        Trace.WriteLine("Adorner Child clicked");
        parentAdorner.Visibility = Visibility.Collapsed;

        Task.Factory.StartNew(() =>
        {
            Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                UIElement underMouse = Mouse.DirectlyOver as UIElement;
                if (underMouse != null) underMouse.RaiseEvent(e);
            }));
        });
    }