2

このFrameworkElement.FindName(string name)メソッドは、XAML 名前スコープからオブジェクトを返します。これとは逆に、オブジェクトを渡してオブジェクトの名前を文字列として取得する方法はありますか?

例:

次の ViewPort3D には、赤い円錐と青い円錐が含まれています。ヒット テストでは、クリックされたコーン オブジェクトを取得できます。しかし、必要なのは、どのコーンがヒットしたか (できれば "redCone" という文字列) に関する情報です。この情報を使用して、たとえば、どの画像をポップアップするかを決定できます。

    <Viewport3D Name="myViewport" MouseDown="myViewport_MouseDown">
        <Viewport3D.Children>
            <ModelVisual3D>
                <ModelVisual3D.Content>
                    <Model3DGroup >
                        <Model3DGroup.Children>

                            <!-- Define a red cone -->
                            <GeometryModel3D x:Name="redCone">
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D />
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>

                            <!-- Define a blue cone -->
                            <GeometryModel3D x:Name="redCone">
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D />
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>

                        </Model3DGroup.Children>
                    </Model3DGroup>
                </ModelVisual3D.Content>
            </ModelVisual3D>
        </Viewport3D.Children>
    </Viewport3D>

私がこれまでに持っているもの:

ハードコーディングされたオブジェクトに対してクリックされたオブジェクトをチェックする必要がある非動的ソリューションがあります。

    private void myViewport_MouseDown(object sender, MouseButtonEventArgs e)
    {
        Point mousePoint = e.GetPosition(this);
        PointHitTestParameters pointparams = new PointHitTestParameters(mousePoint);

        //Test for a result in the Viewport3D
        VisualTreeHelper.HitTest(myViewport, null, HTResult, pointparams);
    }

    public HitTestResultBehavior HTResult(System.Windows.Media.HitTestResult rawresult)
    {
        RayHitTestResult rayResult = rawresult as RayHitTestResult;

        if (rayResult != null)
        {
            RayMeshGeometry3DHitTestResult rayMeshResult = rayResult as RayMeshGeometry3DHitTestResult;

            if (rayMeshResult != null)
            {
                GeometryModel3D hitGeometry = rayMeshResult.ModelHit as GeometryModel3D;

                // Non-dynamic solution:
                if (hitGeometry.Equals(redCone))
                    infoImage.Source = System.IO.Path.Combine(imagesPath, "redCone.png");
                else if (hitGeometry.Equals(blueCone))
                    infoImage.Source = System.IO.Path.Combine(imagesPath, "blueCone.png");

                // Desired solution:
                // string hitName = FindObject(hitGeometry);
                // infoImage.Source = System.IO.Path.Combine(imagesPath, hitName, ".png");
            }
        }

        return HitTestResultBehavior.Stop;
    }

しかし、ご覧のとおりGeometryModel3D、ヒット テストを行い、それと比較したいオブジェクトごとにコードを記述する必要がありhitGeometryます。FindObjectオブジェクトを渡すことで、XAML 名前スコープで「hitGeometry」に割り当てられた名前を返すメソッド (上記のコードのように) があると便利です。

質問:

ヒットしたオブジェクトの名前を取得して、3D ランドスケープが変わるたびにコードを変更する必要がないようにするソリューションはありますか?

注意事項:

  • これはGeometryModel3Dオブジェクト用であるため、Nameプロパティはありません。
  • GeometryModel3D封印されたクラスです
  • ViewPort3D の実際の XAML は .3ds ファイルから生成され、これよりも複雑であるため、構造を変更する余裕はありません。
4

2 に答える 2

2

少し前にそれを行う方法を探していたところ、とにかくクリック可能な要素のリストを保存する必要があることがわかりました... 私たちのプロジェクトでは、実際にクリックしたオブジェクトList<string>の名前を含むを保存することで、この問題を部分的に解決しました。GeometryModel3D

そして、ヒットテスト部分はあなたのものに似ています:

...
    if (rayMeshResult != null)
       {
          GeometryModel3D hitgeo = rayMeshResult.ModelHit as GeometryModel3D;
          foreach (string s in List)
          {
           if (hitgeo.Equals(FindName(s)))
           {
               //do something
           }
         }
       }
于 2013-11-01T06:59:25.850 に答える