Binding with "ElementName" don't work inside <InteractiveVisual3D>

Topics: User Forum
Dec 18, 2006 at 10:13 AM
The binding do not work properly when I use the binding
with "ElementName" inside the <local:InteractiveVisual3D.Visual>
(The binding with Source seems to work)

The following sample xaml code do not work:

<TextBox Name="theTextBox"/>
...
<local:Interactive3DDecorator>
<Viewport3D>
...
<local:InteractiveVisual3D>
<local:InteractiveVisual3D.Visual>
<Button Content="{Binding ElementName=theTextBox, Path=Text}"/>
</local:InteractiveVisual3D.Visual>
...
</local:InteractiveVisual3D>
</Viewport3D>
</local:Interactive3DDecorator>
Coordinator
Dec 18, 2006 at 7:41 PM
I just tried an ElementName binding and was able to get it to work (I just modified the InteractiveViewport3DSample app to have one of the buttons bound using ElementName to a text box - and also moved the sliders on one of the sample meshes to be outside the interactive viewport). Are you doing anything else aside from what you posted in the source code snippet?

-Kurt
Dec 19, 2006 at 9:47 AM
Here a new test sample. There are 4 checkboxes:
- 2 in 2D with default binding,
- 1 in 3D with standard visual material with default binding,
- and the last in 3D with your <InteractiveVisual3D> decoration.

Scenario:
If you check the 1st checkbox, the 2 others checkboxes follow the 1st checkbox behaviour, but NOT the 3rd with the <InteractiveVisual3D> decoration!

If I launch it in Debug Mode, I get the following warnning in the VS Console:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=theCheckBox'. BindingExpression:Path=IsChecked; DataItem=null; target element is 'CheckBox' (Name=''); target property is 'IsChecked' (type 'Nullable`1')

(It is possible to workaround this problem by manually (in c#) rebuild the binding several second after the window initialisation, but this is very boring)

Here the complete sample (to build with the "3DTools" assembly):

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:_3DTools;assembly=3DTools"
Title="Binding" Height="500" Width="500"
>

<Window.Resources>
<MeshGeometry3D x:Key="Plane" Positions="1,1,0 -1,1,0 -1,-1,0 1,-1,0" TextureCoordinates="1,0 0,0 0,1 1,1" TriangleIndices="0 1 2 0 2 3"/>
</Window.Resources>

<StackPanel>
<CheckBox Name="theCheckBox">Originator</CheckBox>
<CheckBox IsChecked="{Binding ElementName=theCheckBox, Path=IsChecked}">Bound to originator</CheckBox>

<local:TrackballDecorator>
<local:Interactive3DDecorator>
<Viewport3D Width="490" Height="400">
<Viewport3D.Camera>
<PerspectiveCamera x:Name="Camera" FieldOfView="45" NearPlaneDistance="0.1" FarPlaneDistance="100" LookDirection="0,0,-1" Position="0,0,6" UpDirection="0,1,0"/>
</Viewport3D.Camera>

<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight Color="#CCC" />
</ModelVisual3D.Content>
</ModelVisual3D>

<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D Geometry="{StaticResource Plane}">
<GeometryModel3D.Transform>
<TranslateTransform3D OffsetZ="0" OffsetX="-1.2" OffsetY="0"/>
</GeometryModel3D.Transform>

<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<VisualBrush>
<VisualBrush.Visual>
<StackPanel Background="White" Width="50" Height="50">
<CheckBox IsChecked="{Binding ElementName=theCheckBox,Path=IsChecked}">Binding</CheckBox>
</StackPanel>
</VisualBrush.Visual>
</VisualBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>

<local:InteractiveVisual3D Geometry="{StaticResource Plane}">
<local:InteractiveVisual3D.Transform>
<TranslateTransform3D OffsetZ="0" OffsetX="1.2" OffsetY="0"/>
</local:InteractiveVisual3D.Transform>

<local:InteractiveVisual3D.Visual>
<StackPanel Background="White" Width="50" Height="50">
<CheckBox IsChecked="{Binding ElementName=theCheckBox, Path=IsChecked}">Binding</CheckBox>
</StackPanel>
</local:InteractiveVisual3D.Visual>
<local:InteractiveVisual3D.Material>
<DiffuseMaterial local:InteractiveVisual3D.IsInteractiveMaterial="True"/>
</local:InteractiveVisual3D.Material>
</local:InteractiveVisual3D>

</Viewport3D>
</local:Interactive3DDecorator>
</local:TrackballDecorator>
</StackPanel>
</Window>
Dec 19, 2006 at 9:49 AM
And No, I am not doing anything else aside from what I posted in my first source code snippet?
Coordinator
Dec 19, 2006 at 10:20 PM
I'm not totally sure yet why this is happening, but here's what I found:

If you take the code here:

<local:InteractiveVisual3D.Material>
<DiffuseMaterial local:InteractiveVisual3D.IsInteractiveMaterial="True"/>
</local:InteractiveVisual3D.Material>

And then simply delete it, you'll get bindings to work. By default we use a DiffuseMaterial, set up exactly as you have it above, so it will give the same results.

When you specify your own material directly, we clone it, and then search through it, looking for the IsInteractiveMaterial dependency property, and then replacing the brush's that have this set to true with the created visual brush. Somehow this process must result in the bindings not getting set up correctly, or I'm not calling a function to have them be set up.

I'll look in to it and see if I can get a more permanant fix and better answer (with the holidays coming up though it might take awhile for a response). But hopefully the above workaround helps in the short term (and if you're looking for a more advanced material I'd recommend just directly modifying the code to use your advanced material as a default).
Coordinator
Dec 19, 2006 at 10:33 PM
This discussion has been copied to Work Item 6660. You may wish to continue further discussion there.
Dec 20, 2006 at 7:49 AM
This very simple workaround solves my issue :)
Thank you for your answer.