diff --git a/src/Avalonia.Controls/Primitives/AdornerLayer.cs b/src/Avalonia.Controls/Primitives/AdornerLayer.cs index 676cdc456a..4b58197ef3 100644 --- a/src/Avalonia.Controls/Primitives/AdornerLayer.cs +++ b/src/Avalonia.Controls/Primitives/AdornerLayer.cs @@ -6,11 +6,12 @@ using System.Collections.Specialized; using System.Linq; using Avalonia.VisualTree; using Avalonia.Media; +using Avalonia.Rendering; namespace Avalonia.Controls.Primitives { // TODO: Need to track position of adorned elements and move the adorner if they move. - public class AdornerLayer : Panel + public class AdornerLayer : Panel, ICustomSimpleHitTest { public static AttachedProperty AdornedElementProperty = AvaloniaProperty.RegisterAttached("AdornedElement"); @@ -137,6 +138,11 @@ namespace Avalonia.Controls.Primitives } } + public bool HitTest(Point point) + { + return Children.Any(ctrl => ctrl.TransformedBounds?.Contains(point) == true); + } + private class AdornedElementInfo { public IDisposable Subscription { get; set; } diff --git a/src/Avalonia.Visuals/Rendering/ICustomSimpleHitTest.cs b/src/Avalonia.Visuals/Rendering/ICustomSimpleHitTest.cs new file mode 100644 index 0000000000..7199053b08 --- /dev/null +++ b/src/Avalonia.Visuals/Rendering/ICustomSimpleHitTest.cs @@ -0,0 +1,12 @@ +namespace Avalonia.Rendering +{ + /// + /// An interface to allow non-templated controls to customize their hit-testing + /// when using a renderer with a simple hit-testing algorithm without a scene graph, + /// such as + /// + public interface ICustomSimpleHitTest + { + bool HitTest(Point point); + } +} diff --git a/src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs b/src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs index fd62c8a59f..d373e7ef2a 100644 --- a/src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs +++ b/src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs @@ -200,7 +200,16 @@ namespace Avalonia.Rendering if (filter?.Invoke(visual) != false) { - bool containsPoint = visual.TransformedBounds?.Contains(p) == true; + bool containsPoint = false; + + if (visual is ICustomSimpleHitTest custom) + { + containsPoint = custom.HitTest(p); + } + else + { + containsPoint = visual.TransformedBounds?.Contains(p) == true; + } if ((containsPoint || !visual.ClipToBounds) && visual.VisualChildren.Count > 0) {