wpfbindinguser-controlsdependency-propertieshelix-3d-toolkit

HelixToolkit: binding to TubeDiameter Property of Torus control in a UserControl gives error


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.


Solution

  • 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