我正试着在画布上命中测试一堆UserControls。我不希望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.
}发布于 2010-08-05 22:00:41
我也遇到过同样的问题,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;
}发布于 2011-08-23 22:15:18
我知道现在回答这个问题太晚了,但这里有一个不同的方法:在UserControl上覆盖HitTestCore,并为它提供预期的默认行为:
protected override System.Windows.Media.HitTestResult HitTestCore(System.Windows.Media.PointHitTestParameters hitTestParameters)
{
return new PointHitTestResult(this, hitTestParameters.HitPoint);
}(当然,您可以使事情复杂化并命中测试实际的子级或它们的边界框的组合,但对我来说,用户控件的边界框已经足够好了;而且,如果您想对几何体进行命中测试,您还需要覆盖第二个重载。)
这使得它可以按预期工作,在过滤器中使用HitTestFilterBehavior.ContinueSkipChildren时滤除子对象。
https://stackoverflow.com/questions/3411910
复制相似问题