关于.net:WPF中鼠标下A型控件的计数

count controls of type A under the mouse in WPF

我在画布上有一些自定义的 A 面板,那里也有 B 面板,我如何计算 A 面板实际上位于鼠标光标处?

我知道这可以通过 VisualTreeHelper.HitTest 来实现,但是没有太多机会,它总是返回自定义面板上的元素或者什么都不返回...

这是我的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<UserControl x:Class="WpfApplication7.UserControl1">
    <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>

<Window x:Class="WpfApplication7.MainWindow"
PreviewMouseLeftButtonDown="Window_PreviewMouseLeftButtonDown" xmlns:my="clr-namespace:WpfApplication7">
    <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>

.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    List<UserControl1> ucs = new List<UserControl1>();

    private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        GetUcsCount(e);
        Console.WriteLine("ucs.Count = {0}", ucs.Count);
    }

    private void GetUcsCount(MouseButtonEventArgs e)
    {
        ucs.Clear();

        Point p = e.GetPosition(this);

        VisualTreeHelper.HitTest(this, null,
            new HitTestResultCallback(MyHitTestCallback),
            new PointHitTestParameters(p));
    }

    HitTestResultBehavior MyHitTestCallback(HitTestResult result)
    {
        if (result.VisualHit.GetType() == typeof(UserControl1))
        {
            ucs.Add(result.VisualHit as UserControl1);
        }

        return HitTestResultBehavior.Continue;
    }
}

result == 0 我点击的任何地方...

alt


对于 HitTestResultCallback 中的每个命中,您可以尝试查找父 UserControl1 并将其添加到列表中(如果尚未添加)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
HitTestResultBehavior MyHitTestCallback(HitTestResult result)
{
    DependencyObject visualHit = result.VisualHit;
    UserControl1 parentUserControl = GetVisualParent<UserControl1>(visualHit);
    if (parentUserControl != null && ucs.IndexOf(parentUserControl) < 0)
    {
        ucs.Add(parentUserControl as UserControl1);
    }
    return HitTestResultBehavior.Continue;
}
public static T GetVisualParent< T >(object childObject) where T : Visual
{
    DependencyObject child = childObject as DependencyObject;
    while ((child != null) && !(child is T))
    {
        child = VisualTreeHelper.GetParent(child);
    }
    return child as T;
}
相关讨论
  • 谢谢,我也观察到了这一点,但现在它返回了太多元素:(不仅在鼠标下
  • @serhio:我在FilterCallback 中找不到任何不在鼠标下的元素的情况。这是什么时候发生的?
  • @Meleak:我明白为什么,实际上 myusercontrol 是透明的,但是很大,并且只有真正可见的子元素..现在,我搜索一种方法,它会在点击子元素而不是透明部分后计算 UserControls ......
  • @serhio:更新了我的答案,如果我理解正确,这应该可以满足您的需求
  • @Meleak:我上传了一张图片以更好地了解情况,蓝色部分在我的情况下是透明的,这就是为什么我得到 2 个控件而不是 1 个 whet hittesting
  • 那么 MyHitTestFilterCallback 呢?
  • 这样做,您将不需要它:) 只需像以前一样将 null 作为参数传递。如果在单击点实际点击了子控件,而不是单击 UserControl1 的"透明"部分,则只会找到父 UserControl1。我用 4 个部分重叠的 UserControl1\'s 进行了尝试,并根据我单击的位置获得了预期的 0 到 4 次点击。

以上是关于.net:WPF中鼠标下A型控件的计数的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>