I'm deriving a control from FrameworkElement to use as a container for a VisualCollection, as I'm doing a lot of custom rendering using DrawingVisuals (creating a game map).
I've got a couple different instances of my container layered on top of each other, and I only want hit testing to affect the layer currently visible, so I tried doing the obvious, and set .IsHitTestVisible=false, which according to MSDN should prevent any child elements being returned as hit results.
However, I am still getting hits returned on the containers that are set .IsHitTestVisible=false. I've tried everything else I can think of, Collapsed, Hidden, Disabled, 0 Opacity, nothing seems to take it out of the hit testing.
I think it's a bug. I used Reflector to understand why the HitTest method returns invisible items and I have found that there is no check for visibility.
My solution is to use overload HitTest with filter:
public static HitTestFilterBehavior HitTestFilterInvisible(DependencyObject potentialHitTestTarget)
{
bool isVisible = false;
bool isHitTestVisible = false;
var uiElement = potentialHitTestTarget as UIElement;
if (uiElement != null)
{
isVisible = uiElement.IsVisible;
if (isVisible)
{
isHitTestVisible = uiElement.IsHitTestVisible;
}
}
else
{
UIElement3D uiElement3D = potentialHitTestTarget as UIElement3D;
if (uiElement3D != null)
{
isVisible = uiElement3D.IsVisible;
if (isVisible)
{
isHitTestVisible = uiElement3D.IsHitTestVisible;
}
}
}
if (isVisible)
{
return isHitTestVisible ? HitTestFilterBehavior.Continue : HitTestFilterBehavior.ContinueSkipSelf;
}
return HitTestFilterBehavior.ContinueSkipSelfAndChildren;
}
...
// usage:
VisualTreeHelper.HitTest(
myHitTestReference,
HitTestFilterInvisible,
hitTestResult =>
{
// code to handle element which is visible to the user and enabled for hit testing.
},
new PointHitTestParameters(myHitTestPoint));
I hope it will help you
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