views:

97

answers:

1

I'm trying to hit-test a bunch of UserControls on a Canvas. I don't want the HitTest() to walk the whole way through the visual tree, so I'm using the FilterCallback to make sure I only hit-test the UserControl.

My problem is that the UserControl never hits, it should, but it doesn't. If I use the FilterCallback, I return that it hit nothing. If I let the HitTest run through the visual tree, it skips the UserControl.

Here's some code:

<Canvas x:Name="Container">
<UserControl>
   <Grid>
      <Rectangle />
   </Grid>
</UserControl>
<UserControl>
   <Grid>
      <Rectangle />
   </Grid>
</UserControl>
</Canvas>

...
VisualTreeHelper.HitTest(Container, OnFilter, OnResult, myPoint);
...

private void OnResult(DependencyObject o)
{
   //I'll get the Rectangle here, but never the userControl  
}

private void OnFilter(DependencyObject o)
{
   //I will get the UserControl here, but even when I do nothing more than continue, it will not trigger a visualHit.  But the child rectangle will.
}
+1  A: 

I had this same problem of HitTest not finding a user control. Apparently this is by design (http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/005dad03-c8eb-405f-9567-50653a0e612c).

I worked around this by handling the hit of some element inside the user control, and then finding the parent user control using the VisualTreeHelper.GetParent method. I'm not very familiar with WPF yet, so I'm not sure if it would be better to use FrameworkElement.Parent property.

However, here is my method for finding the user control (or any visual parent of some required type) after first finding some of its content elements by hit test:

public static T GetVisualParent<T>(this DependencyObject element) where T : DependencyObject
{
    while (element != null && !(element is T))
        element = VisualTreeHelper.GetParent(element);

    return (T)element;
}
Riikka Heikniemi