Page 1 of 1

HitTest doesn't work for IsHitTestVisible?

Posted: 13 Jan 2023, 18:04
by DevFear
The UserControl contains a Grid, which in turn contains a TextBlock. Both UserControl and Grid don't have a Transparent background. TextBlock has the IsHitTestVisible=False property. But VisualTreeHelper.hitTest returns a TextBlock. Can I find out how to properly configure ignoring specific UI elements?

Re: HitTest doesn't work for IsHitTestVisible?

Posted: 13 Jan 2023, 20:16
by sfernandez
It may seem strange but the HitTest method without callbacks returns hits for all visuals, even if they have IsHitTestVisible=False (also those with Visibility=Hidden, or Opacity=0, or IsEnabled=False).

But you can use the version with callbacks to supply your own Filter and Result callbacks:
public static class VisualTreeHelper {
  public static void HitTest(Visual reference,
    HitTestFilterCallback filterCallback,
    HitTestResultCallback resultCallback,
    HitTestParameters hitTestParameters);
}

Re: HitTest doesn't work for IsHitTestVisible?

Posted: 13 Jan 2023, 21:43
by DevFear
Had seen. Thanks. Is there a detailed example of using callbacks in the documentation in C#? For example, what are the HitTestFilterBehavior and HitTestResultBehavior enums responsible for?

Re: HitTest doesn't work for IsHitTestVisible?

Posted: 17 Jan 2023, 21:04
by sfernandez
HitTestFilterBehavior
  • ContinueSkipSelfAndChildren: Do not hit test against the current Visual or its descendants
  • ContinueSkipChildren: Hit test against the current Visual, but not its descendants
  • ContinueSkipSelf: Do not hit test against the current Visual, but hit test against its descendants
  • Continue: Hit test against the current Visual and its descendants
  • Stop: Stop hit testing at the current Visual
HitTestResultBehavior
  • Stop: Stop any further hit testing and return from the callback
  • Continue: Continue hit testing against the next visual in the visual tree hierarchy
To put this into an example that filters only visible elements and stops once the first hit is reached:
DependencyObject hit = null;

bool HitTest(Visual root, Point p)
{
  VisualTreeHelper.HitTest(root, OnFilter, OnHit, new PointHitTestParameters(p);
  return hit != null;
}

HitTestFilterBehavior OnFilter(Visual target)
{
  UIElement element = target as UIElement;
  if (target != null)
  {
    if (!element.IsHitTestVisible || !element.IsVisible)
    {
      return HitTestFilterBehavior.ContinueSkipSelfAndChildren;
    }
  }
  return HitTestFilterBehavior.Continue;
}

HitTestResultBehavior OnHit(HitTestResult result)
{
  hit = result.VisualHit as Visual;
  if (hit != null)
  {
    return HitTestResultBehavior.Stop;
  }
  return HitTestResultBehavior.Continue;
}

Re: HitTest doesn't work for IsHitTestVisible?

Posted: 20 Jan 2023, 07:15
by DevFear
Thanks!