I have the following TorusViewModel which I use as data context for my MainWindow:
public class TorusViewModel : ModelVisual3D, INotifyPropertyChanged
{
private double _torusdiameter = 10.0;
private double _tubediameter = 0.010;
public event PropertyChangedEventHandler PropertyChanged;
public TorusViewModel()
{
}
// diameter property
public double myTorusDiameter
{
get
{
return _torusdiameter;
}
set
{
_torusdiameter = value;
OnPropertyChanged("myTorusDiameter");
}
}
// tube diameter property
public double myTubeDiameter
{
get
{
return _tubediameter;
}
set
{
_tubediameter = value;
OnPropertyChanged("myTubeDiameter");
}
}
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
This is my simple XAML for the MainWindow:
<Grid>
<local:TorusUserControl x:Name="UC1" Padding="5" UCTorusDiameter="{Binding Path=myTorusDiameter, Mode=TwoWay}"
UCTubeDiameter="{Binding Path=myTubeDiameter, Mode=TwoWay}"
/>
</Grid>
with the following UserControl XAML it works:
<UserControl x:Class="Torus2020A.TorusUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:hx="clr-namespace:HelixToolkit.Wpf;assembly=HelixToolkit.Wpf"
xmlns:local="clr-namespace:Torus2020A"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<DockPanel>
<hx:HelixViewport3D x:Name="UCTorusView"
ModelUpDirection="0,1,0"
ZoomExtentsWhenLoaded="True"
ShowCoordinateSystem="True"
PanGesture="LeftClick">
<hx:TorusVisual3D x:Name="UCTorus"
TorusDiameter="{Binding Path=UCTorusDiameter, RelativeSource={RelativeSource AncestorType=UserControl,AncestorLevel=1}, Mode=TwoWay}"
TubeDiameter="1"
ThetaDiv="36"
PhiDiv="24"
/>
<hx:DefaultLights/>
</hx:HelixViewport3D>
</DockPanel>
</Grid>
However, when I bind the TubeDiameter Property to my DependencyProperty using a binding scheme same as TorusDiameter property like this:
<hx:TorusVisual3D x:Name="UCTorus"
TorusDiameter="{Binding Path=UCTorusDiameter, RelativeSource={RelativeSource AncestorType=UserControl,AncestorLevel=1}, Mode=TwoWay}"
TubeDiameter="{Binding Path=UCTubeDiameter, RelativeSource={RelativeSource AncestorType=UserControl,AncestorLevel=1}, Mode=TwoWay}"
ThetaDiv="36"
PhiDiv="24"
/>
I get an exception. This is my code behind for the UserControl:
public partial class TorusUserControl : UserControl
{
//private TorusViewModel UCVisual = new TorusViewModel();
//public ModelVisual3D UCModel = new ModelVisual3D();
public TorusUserControl()
{
InitializeComponent();
//ModelVisual3D UCModel = new ModelVisual3D();
//UCTorus.Fill = Brushes.Red;
//UCTorus.TorusDiameter = 10;
//CTorus.TubeDiameter = 1;
//UCTorus.Transform = new TranslateTransform3D(0, 2, 0);
UCTorusView.Background = Brushes.Aquamarine;
//UCTorusView.Children.Add(UCTorus);
//UCModel.Children.Add(UCTorus);
//UCTorusView.Children.Add(UCTorus);
}
public static readonly DependencyProperty UCTorusDiameterProperty =
DependencyProperty.Register("UCTorusDiameter", typeof(double),
typeof(TorusUserControl));
public double UCTorusDiameter
{
get { return (double)GetValue(UCTorusDiameterProperty); }
set { SetValue(UCTorusDiameterProperty, value); }
}
public static readonly DependencyProperty UCTubeDiameterProperty =
DependencyProperty.Register("UCTubeDiameter", typeof(double),
typeof(TorusUserControl));
public double UCTubeDiameter
{
get { return (double)GetValue(UCTubeDiameterProperty); }
set { SetValue(UCTubeDiameterProperty, value); }
}
}
I would appreciate any hint to what I may be doing wrong.
It turns out that this is a small bug in HelixToolkit. The workaround can be seen in the following:
Torus class TubeDiameter Property binding fails