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 extendsModelVisual3D
to contain anIEnumerable ItemsSource
dependency property. It also contains aDataTemplate3D
to control the rendering of the single elements of the collection.DataTemplate3D
: A custom template, deriving fromDispatcherObject
that defines that uses aVisual3D
as the content property.
The issue
However, I've found a major problem: the Center
s 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?