注: XAML スニペットではカメラとライトの定義を省略して、主に実際の問題に焦点を当てています。
WPFの問題
ObservableCollection
をWPF の 3D クラス ( など) の 1 つにバインドしたいと思い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 コンポーネントのセットを提供するライブラリです。また、例の 1 つ ( 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>
この例は、2 つのクラスのおかげで機能します。
ItemsVisual3D
:依存関係プロパティModelVisual3D
を含むように拡張されたクラス。また、コレクションの単一要素のレンダリングを制御するIEnumerable ItemsSource
も含まれています。DataTemplate3D
DataTemplate3D
:をコンテンツ プロパティとしてDispatcherObject
使用する定義から派生したカスタム テンプレート。Visual3D
問題
ただし、大きな問題が見つかりました。Center
立方体の s は正しく設定されていましたが、他の 2 つのプロパティはまったく設定されておらず、大きなオレンジ色の赤い立方体ではなく、(既定では) 小さな青い立方体になってしまいましたSideLength
。Fill
少し調べてみたところ、DataTemplate3D.csでは境界付きプロパティのみが設定されていることがわかりました。テンプレートで定義されたプロパティを設定する関数にコメント付きのコード ブロックがあったため、問題はすぐに解決しました。
次に、アプリケーションの実行中に、最もあいまいな予期しない動作の 1 つに遭遇しました。境界を除いて、すべてのプロパティが設定されましたCenter
(つまり、原点を中心とする大きなオレンジ色の赤い立方体の束が得られました)。さらに奇妙なことに、関数が返される直前にブレークポイントを設定してプロパティを確認するとCenter
、出力が間違っていても、 を含め、すべて正しく設定されていました!
結論
WPF がコレクションを特定の 3D クラスにバインドする方法を実際に提供していることを見逃していましたか? または、helix ツールキット側で解決策を見つけた人はいますか?