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您实际点击的对象名称的 a 部分解决了这个问题。

命中测试部分与您的相似:

...
    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 回答
2

对于想要实现这一目标的人,

我使用了这种方法:

  <GeometryModel3D x:Name="cube" AutomationProperties.Name="cube1">

然后在鼠标按下事件中:

        // See if we hit a model.
        RayMeshGeometry3DHitTestResult mesh_result =
            result as RayMeshGeometry3DHitTestResult;
        if (mesh_result != null)
        {
            GeometryModel3D model =
                (GeometryModel3D)mesh_result.ModelHit;
            Title = AutomationProperties.GetName(model);

你会得到立方体1

实际上,似乎x:Name在运行时没有用,只有AutomationProperties.Name有效。

这篇文章对我很有帮助: 在 WPF 中,x:Name 和 Name 属性有什么区别?

于 2016-12-21T00:09:19.890 回答