0

我正在将 Silverlight 4 应用程序移植到 WinRT,我使用的以下碰撞检测代码如下所示(并且在 Silverlight 4 中运行良好):

private bool IsCollision(Point p)
{
    var hostPoint = this.canvas.TransformToVisual(this.rootVisual).TransformPoint(p);
    return CheckCollisionPoint(hostPoint, this.canvas);
}

private bool CheckCollisionPoint(Point point, UIElement subTree)
{
    var hits = VisualTreeHelper.FindElementsInHostCoordinates(point, subTree);
    return hits.Count() > 0;
}

但是,在我的 Metro 应用程序中,它根本无法正确检测到碰撞。我认为这可能与使用错误的 rootVisual 有关。计算出 rootVisual 的旧代码是这样的:

private void FindRootVisual()
{
    this.rootVisual = this.canvas;
    while (this.rootVisual.Parent != null)
    {
        this.rootVisual = (FrameworkElement)this.rootVisual.Parent;
    }
}

但在 WinRT 中,this.canvas 的 Parent 为 null。我尝试将 rootVisual 直接设置为我的应用程序的 MainPage 对象,以及 Canvas 所在的 Grid ,但它没有帮助。

这种技术是否仍然适用于 WinRT/Metro,如果可以,我需要使用什么 rootVisual?如果没有,在 WinRT 中进行碰撞检测的更好方法是什么?

4

1 回答 1

0

我发现出了什么问题。首先,我确实需要传入 my MainPage,以便rootVisual在命中测试之前正确转换点。

其次,FindElementsInHostCoordinates似乎将subTree元素本身作为命中返回,因此需要将其过滤掉。事实上,最好明确检查找到的命中是否是您正在碰撞测试的对象,因为我在列表中也有另一个不需要的命中。或者,您可以将IsHitTestVisible不想匹配的项目设置为 false (尽管在画布本身上执行此操作会导致与其任何内容不匹配)

private bool CheckCollisionPoint(Point point, UIElement subTree)
{
    var hits = VisualTreeHelper.FindElementsInHostCoordinates(point, subTree);
    return hits.Any(x => x != subTree);
}
于 2012-09-09T19:12:20.497 回答