I am trying to do hit testing on a collection of user controls added to a canvas at runtime.
My canvas:
<Canvas x:Name="LayoutRoot" Background="White">
<Canvas x:Name="Carrier" Canvas.ZIndex="-1">
</Canvas>
</Canvas>
My canvas code:
public MainPage()
{
InitializeComponent();
var uiElement = new MyUserControl();
this.Carrier.Children.Add(uiElement);
MouseLeftButtonDown += MouseLeftButtonDownHandler;
}
private List<UIElement> HitSprite(Point p)
{
var hitElements =
VisualTreeHelper.FindElementsInHostCoordinates(p, this.Carrier) as List<UIElement>;
return hitElements.Count > 0 ? hitElements : null;
}
private void MouseLeftButtonDownHandler(object sender, MouseButtonEventArgs e)
{
var list = HitSprite(e.GetPosition(this.LayoutRoot));
}
My user control:
<Canvas x:Name="Container" AllowDrop="True">
<StackPanel Name="Description" Height="65" Canvas.ZIndex="2" IsHitTestVisible="False">
<TextBlock Text="Testing" x:Name="Name" FontSize="12" FontWeight="Bold" HorizontalAlignment="Center" IsHitTestVisible="False"/>
<Border Background="Green">
<Image x:Name="Body" Stretch="None" Canvas.ZIndex="0" Height="20" Width="20">
</Image>
</Border>
</StackPanel>
</Canvas>
I’ve tried various combinations of Carrier and LayoutRoot for GetPoint and FindElementsInHostCoordinates but the elements returned are always empty.
What am I doing wrong?
There are a couple of things you have to be aware of about hit testing:
In your case, a combination of this factors was making your user control invisible to hit test:
I made a couple of modifications to your user control XAML and the code behind and I see your user control in the hit test result now:
XAML:
As an additional advice, it is not a good idea to nest canvas panels unless there is a specific reason to do so. Canvas is a special panel in many ways, for example, it won’t clip the items that go outside its bounds, it does not have a size by default unless you set one and it is not a solid object unless you set a background explicitly. Try to use Grid and StackPanel to arrange objects and use the canvas for specific positioning on (x,y) coordinates only.