Search code examples
.netwpftreehittest

HitTest Result Callback doesn't get called


Hi I have the following code, the filter call back gets called but the result call back doesn't, I've been looking at this for some time, any help would be appreciated.

   public HitTestFilterBehavior MyHitTestFilter(DependencyObject o)
   {
        s += o.ToString() + " ";
        //Test for the object value you want to filter.
        if (o.GetType() != typeof(Node))
        {
            // Visual object and descendants are NOT part of hit test results enumeration.
            return HitTestFilterBehavior.ContinueSkipSelf;
        }
        else
        {
            s+="node detected ";
            // Visual object is part of hit test results enumeration.
            return HitTestFilterBehavior.Continue;
        }
    }

Here is the code for the result callback:

public HitTestResultBehavior MyHitTestResult(HitTestResult result)
{
       s += "in result callback ";
       if (result.VisualHit.GetType() == typeof(Node))
        {
            hitResultsList.Add(result.VisualHit as Node);
            s+= "node detected in result callback "
            return HitTestResultBehavior.Stop;

        }
        return HitTestResultBehavior.Continue;
 }

Here is how i am a calling the hit test:

 hitResultsList.Clear();
        VisualTreeHelper.HitTest(designerCanvas, new HitTestFilterCallback(MyHitTestFilter), new HitTestResultCallback(MyHitTestResult), new PointHitTestParameters(End));

Now, the filter callback is going through all the elements and finds the node, however the result callback doesn't get called at all.


Solution

  • The MSDN doc on "Hit Testing in the Visual Layer" contains the strange Note "The hit test filter callback will sometimes be called in cases where the hit test results callback is not called." without further explanation why: http://msdn.microsoft.com/en-us/library/ms752097.aspx#using_a_hit_test_filter_callback

    This is because afaik the filter callback is called for the entire visual tree (of designerCanvas), whereas the result callback is only called for those visuals that really got hit by the PointHitTestParameters in question.

    If you really only want to find the first Node (as you return HitTestResultBehavior.Stop when it's found), you don't need to filter anyway.

    Try leaving out the filter callback to see if Node is really hit. Call

    VisualTreeHelper.HitTest(designerCanvas, null, MyHitTestResult, new PointHitTestParameters(End));