Reputation: 28586
I have the following code
public partial class MainWindow : Window
{
public MainWindow() {
InitializeComponent();
}
List<UIElement> ucs = new List<UIElement>();
private void Window_PreviewMouseLeftButtonDown(object sender,
MouseButtonEventArgs e)
{
ucs.Clear();
Point p = e.GetPosition((UIElement)sender);
VisualTreeHelper.HitTest(this, null,
new HitTestResultCallback(MyHitTestCallback),
new PointHitTestParameters(p));
Console.WriteLine("ucs.Count = {0}", ucs.Count);
foreach (var item in ucs)
{
Console.WriteLine("item: {0}", item.ToString());
}
}
HitTestResultBehavior MyHitTestCallback(HitTestResult result)
{
ucs.Add(result.VisualHit as UIElement);
return HitTestResultBehavior.Continue;
}
}
this is my window
<Window>
<Grid>
<my:UserControl1 HorizontalAlignment="Left" Margin="82,88,0,0" x:Name="userControl11" VerticalAlignment="Top" />
<my:UserControl1 HorizontalAlignment="Left" Margin="168,166,0,0" x:Name="userControl12" VerticalAlignment="Top" />
<my:UserControl1 HorizontalAlignment="Left" Margin="231,130,0,0" x:Name="userControl13" VerticalAlignment="Top" />
</Grid>
</Window>
this is my UC
<UserControl>
<Grid>
<Label Content="Label" Height="44" HorizontalAlignment="Left" Name="label1" VerticalAlignment="Top" FontSize="20" FontWeight="Bold" Width="78" Background="#FF4B9FC4" BorderBrush="#FF020A0D" BorderThickness="1" />
</Grid>
</UserControl>
this is the output when I click ON A USER CONTROL, then on a intersection of 2 UserControls:
ucs.Count = 2
item: System.Windows.Controls.Border
item: System.Windows.Controls.Border
ucs.Count = 3
item: System.Windows.Controls.Border
item: System.Windows.Controls.Border
item: System.Windows.Controls.Border
Why this? Where is the UserControl under the mouse instance?
PS:
Now, when I have on the Label the BorderThickness = 0
ucs.Count = 3
item: System.Windows.Controls.TextBlock
item: System.Windows.Controls.Border
item: System.Windows.Controls.Border
ucs.Count = 3
item: System.Windows.Controls.TextBlock
item: System.Windows.Controls.Border
item: System.Windows.Controls.Border
Upvotes: 1
Views: 1743
Reputation: 14537
The UserControl1
is invisible. Its contents are visible, but your UserControl1
instance itself does not have any visuals of its own. (And it never will. A user control's job is really just to contain other things.)
Hit testing only reports elements that make a direct contribution to the visual tree. And since hit testing considers each element in isolation, this means that elements that are acting purely as containers don't show up. (And a related fact is that hit testing only considers the pixels that actually got painted. So if you have a Border
where you've set the BorderBrush
and a non-zero BorderThickness
but you have no Background
, the hit test will only consider the border outline to be a hit - points inside of the border will not be considered to hit the border because it's not painting anything in its interior.
If you need to do hit testing of a "this thing, or anything inside this thing" style, then either either
IsMouseOver
orThe third one is more complex, but if you need to hit test points other than the one currently under the mouse, you'd need to use it.
Upvotes: 2