UpdateGridLines NullReferenceException

Hi

I have recently upgraded my WPF project from .Net Framework 4.8 to .Net 6 and now I get an exception that previously worked.


Basically I have a SfChart with two different PrimaryAxis (one a DateTime axis, one a TimeSpan axis) that can be switched with a Toggle button.


The switch from one to the other works, but switching back to the original one always fails because of a NullReferenceExcepion.


Anyone experienced something similar and solved it?


Image_5305_1697183587825

Chart snippet:


<xamlExtensions:SfChartExtension x:Name="LiveDataChart" Grid.Row="0" Grid.Column="0"
                                 Margin="0,0,3,0"
                                 Source="{Binding DataSeries, UpdateSourceTrigger=PropertyChanged}">
    <xamlExtensions:SfChartExtension.PrimaryAxis>
        <MultiBinding>
            <MultiBinding.Converter>
                <converters:PrimaryAxisMultiConverter />
            </MultiBinding.Converter>
            <Binding Path="ChartSettings.TimeAxis.DisplayAsTimeSpan" />
            <Binding Source="{StaticResource LiveDataPrimaryTimeSpanAxis}"/>
            <Binding Source="{StaticResource LiveDataPrimaryDateTimeAxis}"/>
        </MultiBinding>
    </xamlExtensions:SfChartExtension.PrimaryAxis>
        <xamlExtensions:SfChartExtension.SeriesTemplateSelector>
            <templateSelector:SeriesDataTemplateSelector LineSeriesTemplate="{StaticResource LiveDataLineSeriesTemplate}" />
        </xamlExtensions:SfChartExtension.SeriesTemplateSelector>
        <xamlExtensions:SfChartExtension.Behaviors>
            <syncfusion:ChartZoomPanBehavior EnableMouseWheelZooming="True" EnablePinchZooming="True" EnableSelectionZooming="True"
                                         EnableZoomingToolBar="{Binding Path=IsChecked, Mode=TwoWay, Source={x:Reference ZoomingToolbarToggleButton}}"
                                         ToolBarItemHeight="20" ToolBarItemMargin="5" ToolBarItemWidth="20"
                                         ZoomMode="XY"/>
        <syncfusion:ChartTrackBallBehavior x:Name="ChartTrackball" UseSeriesPalette="True" />
    </xamlExtensions:SfChartExtension.Behaviors>
</xamlExtensions:SfChartExtension>


Axis snippets:


    <chart:DateTimeAxis x:Key="LiveDataPrimaryDateTimeAxis" ShowGridLines="True" PlotOffset="10"
                             MajorGridLineStyle="{StaticResource GridLineStyle}" MinorGridLineStyle="{StaticResource GridLineStyle}">
        <chart:DateTimeAxis.LabelTemplate>
            <DataTemplate DataType="chart:ChartAxisLabel">
                <Grid Width="70" Height="60">
                    <TextBlock FontSize="12"
                               Text="{Binding LabelContent}"
                               TextWrapping="Wrap" />
                </Grid>
            </DataTemplate>
        </chart:DateTimeAxis.LabelTemplate>
    </chart:DateTimeAxis>


    <chart:TimeSpanAxis x:Key="LiveDataPrimaryTimeSpanAxis"
                        EnableScrollBar="{Binding ChartSettings.TimeAxis.ScrollbarVisible}"
                        LabelsPosition="Outside"
                        ShowGridLines="True"
                        PlotOffset="10"
                        LabelFormat="mm\:ss\:fff"
                        MinorGridLineStyle="{StaticResource GridLineStyle}"
                        MajorGridLineStyle="{StaticResource GridLineStyle}"
                        ShowTrackBallInfo="{Binding ChartSettings.TrackballTooltipDateTimeAxis}">
        <chart:TimeSpanAxis.LabelTemplate>
            <DataTemplate DataType="chart:ChartAxisLabel">
                <Grid Width="70" Height="60">
                    <TextBlock FontSize="12"
                               Text="{Binding LabelContent}"
                               TextWrapping="Wrap" />
                </Grid>
            </DataTemplate>
        </chart:TimeSpanAxis.LabelTemplate>
    </chart:TimeSpanAxis>


Converter Snippet:

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values.Length < 3 || values[0] is not bool || values[1] is not ChartAxisBase2D || values[2] is not ChartAxisBase2D)
            {
                return DependencyProperty.UnsetValue;
            }


            var dateTimeAxis = (bool) values[0];


            return dateTimeAxis ? values[1] : values[2];


        }

7 Replies 1 reply marked as answer

SA Saiyath Ali Fathima Bee Moidhin Abdhul Kathar Syncfusion Team October 16, 2023 01:30 PM UTC

Hi Lukas,


 We have analyzed the provided code snippet and suspect that the issue may be caused by the static resource. We have attached a runnable sample without any issues. Could you please make the necessary changes to reproduce the issue with this attachment or provide more details? This will help us with further validation.


We will check with our development team and provide an update tomorrow, October 17, 2023. Thank you for your understanding.

 

Regards,

Saiyath Ali Fathima M


Attachment: Chart_773061d1.zip


LR Lukas R October 16, 2023 01:50 PM UTC

Thanks for the reply!


I checked your sample and it works indeed. But I could replicate the error with a small change. If the axis are the same instance as before the change I get the exact same issue as in my original question:


    public partial class MainWindow : Window
    {
        public List<DateTime> TimeData { get; set; }
        public TimeSpanAxis TimeSpanAxis { get; set; }
        public DateTimeAxis DateTimeAxis { get; set; }


        public MainWindow()
        {
            InitializeComponent();
            TimeSpanAxis = new TimeSpanAxis();
            DateTimeAxis = new DateTimeAxis();
        }


        private void Button_Click1(object sender, RoutedEventArgs e)
        {
            sfChartExt.PrimaryAxis = TimeSpanAxis;
        }


        private void Button_Click2(object sender, RoutedEventArgs e)
        {
            sfChartExt.PrimaryAxis = DateTimeAxis;
        }
    }


Process:

  • Select DateTimeAxis -> works
  • Select TimeSpanAxis -> works
  • Select DateTimeAxis again -> crash
(the same if we start with TimeSpan Axis)

Image_8648_1697464085824

I'll probably be able to adjust my code to create a new Axis instance when changing from TimeSpan to  DateTime, but I don't think this behavior is intended.

Best regards
Lukas


SA Saiyath Ali Fathima Bee Moidhin Abdhul Kathar Syncfusion Team October 17, 2023 01:18 PM UTC

Hi Lukas,

 

We have identified the reported issue, "ArgumentNullException is thrown while switching between pre-defined axis instance" as a bug and have added it to our bug report list. We plan to include the fix in our upcoming weekly NuGet release on October 24, 2023. You can track the status of the bug using the following link:

 

https://www.syncfusion.com/feedback/47706/argumentnullexception-is-thrown-while-switching-between-pre-defined-axis-instance

 

Regards,

Saiyath Ali Fathima M



SA Saiyath Ali Fathima Bee Moidhin Abdhul Kathar Syncfusion Team October 25, 2023 04:14 AM UTC

Hi Lukas,

 

Kindly apologize for the ongoing delay. Unfortunately, due to some pending automation testing, we were unable to include the fix in the recent weekly NuGet release. We assure that the fix will be incorporated in the upcoming weekly release, which is scheduled for October 31, 2023. We appreciate your patience.

 

Regards,

Saiyath Ali Fathima M



SA Saiyath Ali Fathima Bee Moidhin Abdhul Kathar Syncfusion Team October 26, 2023 12:39 PM UTC

Hello Lukas,


We have discussed the reported issue with our development team. The exception is occurring due to the disposal of axis items, which is done to prevent memory leaks and improve performance.


However, we can resolve this issue by using the Clone method in the axis. This method is used to carry forward the axis settings from the initialized property. For your reference, we have provided a code snippet, a demo, and a runnable sample below.


 public partial class MainWindow : Window

 {

     public TimeSpanAxis TimeSpanAxis { get; set; }

     public DateTimeAxis DateTimeAxis { get; set; }

 

     public MainWindow()

     {

         InitializeComponent();

         TimeSpanAxis = new TimeSpanAxis()

         {

             Background = new SolidColorBrush(Colors.Aqua),

             PlotOffset=20,

             EdgeLabelsDrawingMode=EdgeLabelsDrawingMode.Shift

         };

         DateTimeAxis = new DateTimeAxis()

         {

             Background = new SolidColorBrush(Colors.LimeGreen),

             PlotOffset = 20,

             EdgeLabelsDrawingMode = EdgeLabelsDrawingMode.Shift

         };

     }

 

     private void Button_Click1(object sender, RoutedEventArgs e)

     {

         sfChartExt.PrimaryAxis = (ChartAxisBase2D)TimeSpanAxis.Clone();

     }

 

     private void Button_Click2(object sender, RoutedEventArgs e)

     {

         sfChartExt.PrimaryAxis = (ChartAxisBase2D)DateTimeAxis.Clone();

     }

 }



Please don't hesitate to reach out if you require any further assistance.


Best regards,

Saiyath Ali Fathima M


Attachment: Chart_6d2ae4.zip

Marked as answer

LR Lukas R October 26, 2023 02:13 PM UTC

Hello


Thank you! This is the perfect solution for my use-case.


Best Regards

Lukas



PR Preethi Rajakandham Syncfusion Team October 27, 2023 04:38 AM UTC

Hi Lukas, 

You're welcome. 

We are glad to know that the reported problem has been resolved. Please let us know if you require any further assistance on this, we will be happy to assist you. 

Regards,

Preethi R


Loader.
Up arrow icon