This is a migrated thread and some comments may be shown as answers.

RadCartesianChart reusing MVVM DataContext

4 Answers 157 Views
ChartView
This is a migrated thread and some comments may be shown as answers.
Rik
Top achievements
Rank 1
Rik asked on 27 Jul 2017, 10:12 AM

I have a RadCartesianChart defined in XAML with multiple series. Each series has the ItemsSource, HorizontalAxis, VerticalAxis and Visibility bound to MVVM model properties. The ChartView itself has the DataContext bound inherently from the DataContext of my chartviewer usercontrol's DataContext.

When my control is first displayed, everything works as expected, the chart is displayed correctly and I can switch through the different series with different data and different label formats.

The chartviewer control is part of a ContentControl which picks the relevant View from the assigned DataContext type. This is switched depending on user input.

Firstly, if I navigate away from the chartviewer control I have to use the following code to prevent a "Cannot modify the logical children for this node at this time because a tree walk is in progress" exception from the ChartView:-

private void ChartViewer_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
      if (e.NewValue == null)
      {
            chartCart.DataContext = null;
            chartCart.UpdateLayout();
      }
}

Secondly if I then go back to the ChartViewer reusing he same MVVM model that was previously used, the ChartView now show "HorizontalAxis not set" and "VerticalAxis not set". It does not matter what I change on the model, I cannot get the chart to show anything else. When using Visual Studio to look at the ChartView, the DataContext binding is valid, the series are all there, and all of the series have correct bindings to the model properties and seem to be correct. I noticed that the axes get their Chart property set when assigned to the series, so I have tried rebuilding the axes in the same way I do when the chart is working (first view).

I have also tried binding the DataContext of the ChartView to a different DependencyProperty which allows me to get away from the exception (noted above), but still the same problem. I have tried stepping through the Visual Tree and rebuilding all of the bindings to ensure they are all active, but this has no effect.

What would cause the EmptyContent message to show when there are series available, each with axes set and are visible, and have point data?

4 Answers, 1 is accepted

Sort by
0
Martin Ivanov
Telerik team
answered on 31 Jul 2017, 12:33 PM
Hello Richard,

I went through the provided information, but without your implementation I cannot tell what happens. Can you prepare some runnable code that demonstrates the issue and post it here? This will allow me to test it and check what happens.

As a side note, I deleted the duplicate forum post.

Regards,
Martin Ivanov
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Rik
Top achievements
Rank 1
answered on 02 Aug 2017, 08:47 AM

Here is a brand new project with a cut-down version of what we are developing. It shows exactly the same issue. I have added the DataContextChanged event handler to the ChartViewerView to get around the issue of the "Cannot modify the logical children ..." issue again. It would be good if you could comment it out and see if you can also find a better solution or fix for this issue.

To use the demo, load it up. Clicking on either of the buttons will show a different view. With the DataContextChanged disabled, you cannot navigate away from the "Chart" screen without a blowup. When in place, returning to the "Chart" screen shows the horizontal and vertical axis "EmptyContent" message. All that is happening is a ContentControl is creating a new view and hooking it up to the supplied model.

0
Accepted
Martin Ivanov
Telerik team
answered on 07 Aug 2017, 08:57 AM
Hi Richard,

Thank you for the attached project. It seems that this data context propagation confuses the chart's axis and once you unload it from the visual tree then the chart won't render it properly, which leads to the reported behavior (the axis not set message).

To resolve this, instead of handling the exception by setting the Chart's DataContext to null, you can set the series' vertical/horizontal axis to null. Here is an example in code:
private void ChartViewerView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if (e.NewValue == null)
    {
        this.barSeries.VerticalAxis = null;
        this.barSeries.HorizontalAxis = null;
        this.scatterSeries.VerticalAxis = null;
        this.scatterSeries.HorizontalAxis = null;
    }
}

I hope this helps.

Regards,
Martin Ivanov
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Rik
Top achievements
Rank 1
answered on 08 Aug 2017, 11:14 AM

Thank you Martin, that seems to do the trick. I actually used the following based on your answer.

If (e.NewValue == null)
  foreach (CartesianSeries series in chart.Series)
  {
    series.VerticalAxis = null;
    series.HorizontalAxis = null;
  }
}

It's a bit odd that by removing it from the visual tree in this way would prevent the chart showing when a new one is created after the view is switched back. Is there some sort of caching happening on the ContentControl which means it tries to re-use the same view and re-add it to the visual tree?

Anyhow, we have a working switchable chart view so thank you for investigating this issue.

Kind regards
Rik

Tags
ChartView
Asked by
Rik
Top achievements
Rank 1
Answers by
Martin Ivanov
Telerik team
Rik
Top achievements
Rank 1
Share this question
or