注意:我在 XAML 片段中省略了相机和灯光定义,主要关注真正的问题。
WPF的问题
我想以类似于以下的方式将一个绑定ObservableCollection
到 WPF 的 3D 类之一(如ModelVisual3D
):
<Viewport3D>
<Viewport3D.Children>
<Some3DClass ItemsSource="{Binding Objects}">
<Some3DClass.ItemTemplate>
<!-- definition of the template -->
</Some3DClass.ItemTemplate>
</Viewport3D.Children>
</Viewport3D>
但是,经过一些研究和测试,我在 WPF 中没有发现任何类似的东西。
使用 Helix Toolkit 的解决方案(有点)
Helix 工具包是一个为 WPF 提供一组 3D 组件的库。此外,我发现其中一个示例 ( DataTemplate ) 声称可以提供我所需要的。
它是如何工作的?
这是示例的 xaml 部分的类似实现:
<helix:HelixViewport3D>
<local:ItemsVisual3D ItemsSource="{Binding Objects}">
<local:ItemsVisual3D.ItemTemplate>
<DataTemplate3D>
<CubeVisual3D Center="{Binding Position}" SideLength="3" Fill="OrangeRed"/>
</DataTemplate3D>
</local:ItemsVisual3D.ItemTemplate>
</local:ItemsVisual3D>
</helix:HelixViewport3D>
这个例子的工作归功于两个类:
ItemsVisual3D
:扩展ModelVisual3D
以包含IEnumerable ItemsSource
依赖属性的类。它还包含一个DataTemplate3D
用于控制集合的单个元素的呈现。DataTemplate3D
:一个自定义模板,派生自DispatcherObject
使用 aVisual3D
作为内容属性的定义。
问题
但是,我发现了一个主要问题:Center
立方体的 s 设置正确,但其他两个属性根本没有设置,SideLength
最终Fill
得到小的蓝色立方体(默认情况下)而不是更大的橙红色立方体。
我调查了一下,我意识到在DataTemplate3D.cs中,只设置了有界属性。我很快解决了这个问题,因为函数中有一个注释代码块,它设置了模板中定义的属性。
然后,在运行该应用程序时,我遇到了一个最令人费解的意外行为:所有属性都已设置,除了有界的Center
(即,我得到了一堆以原点为中心的大橙红色立方体)。更奇怪的是,当我在函数返回检查属性之前设置断点时,它们都设置正确,包括Center
,即使输出错误!
结论
我是否错过了 WPF 确实提供了一种将集合绑定到特定 3D 类的方法?或者有人在 helix 工具包方面找到了解决方案吗?