diff --git a/src/Wpf.Ui/Extensions/UiElementExtensions.cs b/src/Wpf.Ui/Extensions/UiElementExtensions.cs
index bf6d4639d..95b3f0f47 100644
--- a/src/Wpf.Ui/Extensions/UiElementExtensions.cs
+++ b/src/Wpf.Ui/Extensions/UiElementExtensions.cs
@@ -10,7 +10,7 @@ internal static class UiElementExtensions
///
/// Do not call it outside of NCHITTEST, NCLBUTTONUP, NCLBUTTONDOWN messages!
///
- /// if mouse is over the element. otherwise.
+ /// if mouse is over the element. otherwise.
public static bool IsMouseOverElement(this UIElement element, IntPtr lParam)
{
// This method will be invoked very often and must be as simple as possible.
@@ -21,25 +21,18 @@ public static bool IsMouseOverElement(this UIElement element, IntPtr lParam)
try
{
- var mousePosScreen = new Point(Get_X_LParam(lParam), Get_Y_LParam(lParam));
-
- return new Rect(default, element.RenderSize).Contains(element.PointFromScreen(mousePosScreen))
- && element.IsHitTestVisible
- && (
- !(element is System.Windows.Controls.Panel panel)
- || // If element is Panel, check if children at mousePosRelative is with IsHitTestVisible false.
- (
- panel
- .Children.OfType()
- .FirstOrDefault(child =>
- new Rect(default, child.RenderSize).Contains(
- child.PointFromScreen(mousePosScreen)
- )
- )
- ?.IsHitTestVisible
- ?? false
- )
- );
+ // Ensure the visual is connected to a presentation source (needed for PointFromScreen).
+ if (PresentationSource.FromVisual(element) == null)
+ {
+ return false;
+ }
+
+ var mousePosition = new Point(Get_X_LParam(lParam), Get_Y_LParam(lParam));
+
+ // If element is Panel, check if children at mousePosition is with IsHitTestVisible false.
+ return new Rect(default, element.RenderSize).Contains(element.PointFromScreen(mousePosition)) &&
+ element.IsHitTestVisible &&
+ (element is not System.Windows.Controls.Panel panel || IsChildHitTestVisibleAtPointFromScreen(panel, mousePosition));
}
catch
{
@@ -56,4 +49,17 @@ private static int Get_Y_LParam(IntPtr lParam)
{
return (short)(lParam.ToInt32() >> 16);
}
+
+ private static bool IsChildHitTestVisibleAtPointFromScreen(System.Windows.Controls.Panel panel, Point mousePosition)
+ {
+ foreach (UIElement child in panel.Children)
+ {
+ if (new Rect(default, child.RenderSize).Contains(child.PointFromScreen(mousePosition)))
+ {
+ return child.IsHitTestVisible;
+ }
+ }
+
+ return false;
+ }
}