helix-toolkit / helix-toolkit

Helix Toolkit is a collection of 3D components for .NET.
http://helix-toolkit.org/
MIT License
1.84k stars 661 forks source link

ColorAxis - Canvas is null #70

Closed dgwaldo closed 9 years ago

dgwaldo commented 9 years ago

Often I get Canvas is null error coming from things that inherit from the ColorAxis class. After looking at the source, I was able to fix it by adding to the protected constructor. this.Canvas = new Canvas();

    /// <summary>
    /// Initializes a new instance of the <see cref="ColorAxis" /> class.
    /// </summary>
    protected ColorAxis()
    {
        this.Canvas = new Canvas();
        this.SizeChanged += (s, e) => this.UpdateVisuals();
        this.Loaded += (s, e) => this.UpdateVisuals();
    }
objorke commented 9 years ago

Wouldn't it be better to add null checks for Canvas?

dgwaldo commented 9 years ago

To highlight the bug I modified the DNA Demo.

<Window x:Class="DnaDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:helix="clr-namespace:HelixToolkit.Wpf;assembly=HelixToolkit.Wpf"
Title="DnaDemo" Height="480" Width="640"
Background="Black">

<Window.Resources>
    <!-- http://en.wikipedia.org/wiki/Rainbow -->
    <LinearGradientBrush x:Key="RainbowBrush" StartPoint="0,1" EndPoint="1,0">
        <LinearGradientBrush.GradientStops>
            <GradientStop Color="Red" Offset="0"/>
            <GradientStop Color="Orange" Offset="0.17"/>
            <GradientStop Color="Yellow" Offset="0.33"/>
            <GradientStop Color="Green" Offset="0.5"/>
            <GradientStop Color="Blue" Offset="0.67"/>
            <GradientStop Color="Indigo" Offset="0.84"/>
            <GradientStop Color="Violet" Offset="1"/>
        </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
</Window.Resources>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <helix:HelixViewport3D x:Name="view1" 
                       ShowFrameRate="True" 
                       InfiniteSpin="true" 
                       IsHeadLightEnabled="True"
                       InfoBackground="Transparent"
                       InfoForeground="White"
                       CameraRotationMode="Trackball"
                       ShowCoordinateSystem="True"
                       CoordinateSystemLabelForeground="White"
                       CoordinateSystemLabelX="x"
                       CoordinateSystemLabelY="y"
                       CoordinateSystemLabelZ="z"
                       Title="Double helix"
                       SubTitle="Colored with a 'rainbow' brush" 
                       TextBrush="White">
        <ModelVisual3D x:Name="model">
            <ModelVisual3D.Transform>
                <TranslateTransform3D OffsetZ="-15"/>
            </ModelVisual3D.Transform>

            <helix:HelixVisual3D Radius="2" Diameter="0.5" Turns="3" Length="30" Fill="{StaticResource RainbowBrush}"/>
            <helix:HelixVisual3D Radius="2" Diameter="0.5" Turns="3" Length="30" Phase="180" Fill="{StaticResource RainbowBrush}"/>

        </ModelVisual3D>

    </helix:HelixViewport3D>

    <helix:RangeColorAxis Height="200"  Grid.Column="1" Width="50" Minimum="0" Maximum="1" Step=".1" Margin="8" Padding="4 0 4 0"  MinimumTextureCoordinate="0" MaximumTextureCoordinate="1"
                      ColorScheme="{StaticResource RainbowBrush}" Background="#80FFFFFF" Position="Right"/>
</Grid>

The error does occur in the UpdateVisuals() method. The following code with null check prevents the visual from updating if the canvas is null. It looks like the dependency properties are changing before OnApplyTemplate() is called causing this... In this case I'd say yes the null check is more appropriate.

    /// <summary>
    /// Updates the visuals.
    /// </summary>
    protected void UpdateVisuals()
    {
        if (Canvas == null) return;
        this.Canvas.Children.Clear();
        this.AddVisuals();
    }

Forgive my ignorance, but is the easiest thing for you, to have me submit a pull request for something like this?

objorke commented 9 years ago

Yes, please create a pull request even if it is only a line of code :-) Note that the code base is mostly StyleCop compliant, and the return; should be enclosed by { }

dgwaldo commented 9 years ago

Thanks, I loaded StyleCop for when I work with your tool kit. I submitted a pull request, thanks for this project, it makes working with the WPF 3D fun. Going to do a 15 minute presentation on it at our .Net user group this month...

objorke commented 9 years ago

Cool! Thanks for your contribution! Post a screenshot or link to your presentation on the discussion forum or gitter.im!