locked
VisualTreeHelper.HitTest not working for collision detection RRS feed

  • Question

  • I'm trying to figure out how hittest works and there is not much documentation on it.  Why isn't this piece of code working? Any takers? Thanks in advance.  I'm really confused as to what the parameters are for and how they are ordered.  Why does it need the first param?  Why do you need a filter and result callbacks.  Also why does it need the geoparams at the end?

     

    1 using System;  
    2 using System.Collections.Generic;  
    3 using System.Linq;  
    4 using System.Text;  
    5 using System.Windows;  
    6 using System.Windows.Controls;  
    7 using System.Windows.Data;  
    8 using System.Windows.Documents;  
    9 using System.Windows.Input;  
    10 using System.Windows.Media;  
    11 using System.Windows.Media.Imaging;  
    12 using System.Windows.Navigation;  
    13 using System.Windows.Shapes;  
    14  
    15 namespace HitTestWPFApp  
    16 {  
    17     /// <summary>  
    18     /// Interaction logic for Window1.xaml  
    19     /// </summary>  
    20     public partial class Window1 : Window  
    21     {  
    22         public Window1()  
    23         {  
    24             InitializeComponent();  
    25         }  
    26  
    27         private Point oldPoint;  
    28         private Point newPoint;  
    29         private double origOffsetLeft;  
    30         private double origOffsetTop;  
    31  
    32  
    33  
    34  
    35         private void Path1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)  
    36         {  
    37             Path p = (Path)sender;  
    38             oldPoint = e.GetPosition(this);  
    39             origOffsetLeft = Canvas.GetLeft(p);  
    40               
    41             origOffsetTop = Canvas.GetTop(p);  
    42  
    43             MakeTopMost(p);  
    44             p.MouseMove += new MouseEventHandler(p_MouseMove);  
    45  
    46             Geometry geo = Path1.RenderedGeometry.Clone();  
    47             VisualTreeHelper.HitTest(Path1,  
    48                 (HitTestFilterCallback)delegate(DependencyObject potentialHitTestTarget)  
    49                 {  
    50                     Console.WriteLine("PT:" + ((Path)potentialHitTestTarget).Name);  
    51                     //if (potentialHitTestTarget == path)  
    52                     //    return HitTestFilterBehavior.ContinueSkipSelfAndChildren;  
    53  
    54                     return HitTestFilterBehavior.Continue;  
    55                 },  
    56                 (HitTestResultCallback)delegate(HitTestResult result)  
    57                 {  
    58                     GeometryHitTestResult geoResult = (GeometryHitTestResult)result;  
    59                     //Console.WriteLine("PT:" + ((Path)geoResult.VisualHit).Name);  
    60                     //Console.WriteLine(geoResult.IntersectionDetail.ToString());  
    61                     /*
    62                     if (result.VisualHit == controller)
    63                     {
    64                         puck.Speed *= -(controller.Speed);
    65
    66                         //Console.WriteLine("Hit");
    67                         //label1.Text = geoResult.IntersectionDetail.ToString();
    68                         //count += 1;
    69
    70                         //label1.Text = "The Puck Hit Border " + count + "Times: " + geoResult.IntersectionDetail.ToString();;
    71
    72                         return HitTestResultBehavior.Stop;
    73
    74                     }
    75                     */ 
    76                     return HitTestResultBehavior.Continue;  
    77  
    78                 }, new GeometryHitTestParameters(geo));  
    79               
    80         }  
    81  
    82         private void MakeTopMost(Path dp)  
    83         {  
    84             //Console.WriteLine(Canvas.GetZIndex(this.Path1) + ":" + Canvas.GetZIndex(this.Path2));  
    85             DependencyObject d = VisualTreeHelper.GetParent(dp);  
    86             for (int i = 0; i < VisualTreeHelper.GetChildrenCount(d); i++)  
    87             {  
    88                 Canvas.SetZIndex((UIElement)VisualTreeHelper.GetChild(d, i), i);  
    89                 Canvas.SetZIndex(dp, i+1);  
    90             }  
    91              
    92         }  
    93  
    94         private void p_MouseMove(object sender, MouseEventArgs e)  
    95         {  
    96             Path p = (Path)sender;  
    97             if (e.LeftButton == MouseButtonState.Pressed)  
    98             {  
    99  
    100                 newPoint = e.GetPosition(this);  
    101                 Canvas.SetLeft(p, origOffsetLeft + (newPoint.X - oldPoint.X));  
    102  
    103                 Canvas.SetTop(p, origOffsetTop + (newPoint.Y - oldPoint.Y));  
    104  
    105  
    106  
    107             }  
    108             else 
    109             {  
    110                 p.MouseMove -= new MouseEventHandler(p_MouseMove);  
    111             }  
    112         }  
    113  
    114           
    115         private void Path1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)  
    116         {  
    117             Path p = (Path)sender;  
    118             p.MouseMove -= new MouseEventHandler(p_MouseMove);  
    119         }  
    120     }  
    121 }  
    122  
    Tuesday, March 3, 2009 8:10 PM

Answers

  • Hello Jody,
      
        Why does it need the first param?

        The first visual object parameter identifies the starting point in the visual tree for the hit test search.

        
        Why do you need a result callbacks

       We can enumerate all visual objects in a visual tree whose geometry contains a specified coordinate value. This allows you to identify all visual objects, even those that may be partly or wholly obscured by other visual objects. To enumerate visual objects in a visual tree use the HitTest method with a hit test callback function. The hit test callback function is called by the system when the coordinate value you specify is contained in a visual object.

       Why do you need a filter callbacks

    You can use an optional hit test filter to restrict the objects that are passed on to the hit test results. This allows you to ignore parts of the visual tree that you are not interested in processing in your hit test results.
       

       More in Hit Testing in the Visual Layer

       Also why does it need the geoparams at the end?

      GeometryHitTestParameters Specifies a Geometry as the parameter to be used for hit testing a visual tree.

     More in http://msdn.microsoft.com/en-us/library/system.windows.media.geometryhittestparameters.aspx

      Related links:

        http://msdn.microsoft.com/en-us/library/system.windows.media.visualtreehelper.hittest(VS.85).aspx

        http://msdn.microsoft.com/en-us/library/ms608753(VS.85).aspx

        Could you please give a complete sample to test?

      Good luck.


    Please mark the replies as answers if they help and unmark them if they provide no help
    • Marked as answer by Hua Chen Tuesday, March 10, 2009 10:42 AM
    Friday, March 6, 2009 7:30 AM