Note: I've omitted camera and light definitions in the XAML snippets to focus majorly on the real problem.
The problem with WPF
I would like to bind an ObservableCollection to one of WPF's 3D classes (like ModelVisual3D) In a way similar to the following:
<Viewport3D>
<Viewport3D.Children>
<Some3DClass ItemsSource="{Binding Objects}">
<Some3DClass.ItemTemplate>
<!-- definition of the template -->
</Some3DClass.ItemTemplate>
</Viewport3D.Children>
</Viewport3D>
However, after some research and testing, I did not found anything similar in WPF.
A solution (sort of) with Helix Toolkit
Helix toolkit is a library that offers a set of 3D components for WPF. Also, I've discovered that one of the examples (DataTemplate) claimed to provide exactly what I needed.
How does it work?
Here is a similar implementation of the xaml part of the example:
<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>
This example works thanks to two classes:
ItemsVisual3D: A class that extendsModelVisual3Dto contain anIEnumerable ItemsSourcedependency property. It also contains aDataTemplate3Dto control the rendering of the single elements of the collection.DataTemplate3D: A custom template, deriving fromDispatcherObjectthat defines that uses aVisual3Das the content property.
The issue
However, I've found a major problem: the Centers of the cubes were set correctly, but the other two properties, SideLength and Fill were not set at all, ending up with small blue cubes (by default) instead of bigger orange red cubes.
I've investigated a bit, and I realized that in DataTemplate3D.cs, only the bounded properties are set. I resolved the problem quickly, because there was a commented block of code in the function, that sets the properties defined in the template.
Then, while running the application, I've encountered one of the most obscure unexpected behaviors: All the properties were set, except for the bounded Center (i.e. I got a bunch of big orange red cubes all centered at the origin). More strangely, when I've set a breakpoint just before the function returned to check the properties, they were all set correctly, including Center, even if the output is wrong!
Conclusion
Did I miss that WPF really provides a way to bind a collection to a particular 3D class? Or did anyone found a solution on the helix toolkit side?