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 は null の Parent を持っています。rootVisual をアプリケーションの MainPage オブジェクトと、Canvas がある Grid に直接設定しようとしましたが、役に立ちません。

この手法は WinRT/Metro でも機能する必要がありますか? その場合、どの rootVisual を使用する必要がありますか? そうでない場合、WinRT で衝突検出を行うより良い方法は何でしょうか?

4

1 に答える 1

0

何が悪いのかわかりました。まず、ヒットテストの前にポイントを正しく変換するために自分を渡す必要があり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 に答える