4

我正在尝试在 Canvas 上测试一堆 UserControl。我不希望 HitTest() 一直遍历可视化树,所以我使用 FilterCallback 来确保我只对 UserControl 进行命中测试。

我的问题是 UserControl 从来没有命中,它应该,但它没有。如果我使用 FilterCallback,我会返回它没有命中任何内容。如果我让 HitTest 在可视化树中运行,它会跳过 UserControl。

这是一些代码:

<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.
}
4

2 回答 2

12

我知道现在回答这个问题已经很晚了,但这里是:另一种方法是覆盖 UserControl 上的 HitTestCore 并为其提供预期的默认行为:

protected override System.Windows.Media.HitTestResult HitTestCore(System.Windows.Media.PointHitTestParameters hitTestParameters)
{
    return new PointHitTestResult(this, hitTestParameters.HitPoint);
}

(当然你可以使事情复杂化并对实际的孩子或他们的边界框的组合进行命中测试,但对我来说,用户控件的边界框已经足够好了;另外,如果你想对几何图形进行命中测试,你需要也覆盖第二个重载。)

这使它按预期工作,在过滤器中使用时过滤掉子项HitTestFilterBehavior.ContinueSkipChildren

于 2011-08-23T14:15:17.613 回答
2

我遇到了同样的问题,即 HitTest 找不到用户控件。显然这是设计使然(http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/005dad03-c8eb-405f-9567-50653a0e612c)。

我通过处理用户控件中某些元素的命中来解决这个问题,然后使用 VisualTreeHelper.GetParent 方法找到父用户控件。我对 WPF 还不是很熟悉,所以我不确定使用 FrameworkElement.Parent 属性是否会更好。

但是,这是我在通过命中测试首先找到它的一些内容元素之后找到用户控件(或任何所需类型的任何可视父级)的方法:

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

    return (T)element;
}
于 2010-08-05T14:00:41.263 回答