Search code examples
c#wpfmvvmlivecharts

Why is MVVM pattern not working for ChartValues?


I have some issues with MVVM, I am trying to plot the x and y values on a chart, I populate my list chartValues, but when I try to set it in my CurrentLUT and I load the program the x and y values do not appear, only the empty diagram. I have binded the Title with the CurrentLUT, so that in the Legend of the diagram appears the CurrentLUT (selected item from a combobox) and I tried to do the same with the points of my chart, but I can´t find my error.

xaml

<ComboBox ItemsSource="{Binding AllLUTLibraries}" SelectedItem="{Binding CurrentLUT}"/>
<lvc:CartesianChart Series="{Binding SeriesCollection}"/>

xaml.cs

 public List<ILUTLibrary> AllLUTLibraries { get; } = Objects.LUTLibraries.Instance.AllLUTLibraries; 

 private ILUTLibrary currentLUT = Objects.LUTLibraries.Instance.AllLUTLibraries[0];
 public ILUTLibrary CurrentLUT

 {
        get
        {
               return currentLUT;
        }
        set
        {
               currentLUT = value;
               lineSeries.Title = currentLUT.ToString();
               lineSeries.Values = chartValues;
               OnPropertyChanged();
        }
 }

 private SeriesCollection seriesCollection;
 public SeriesCollection SeriesCollection
 {
        get
        {
               return seriesCollection;
        }
        set
        {
               seriesCollection = value;
               OnPropertyChanged();
        }
 }

 public LineSeries lineSeries = new LineSeries //line properties
 {
 };

 public NewLUT_ViewModel() //constructor
 {     
        SeriesCollection = new SeriesCollection { lineSeries };
 }

 private ChartValues<ObservablePoint> chartValues;
 public ChartValues<ObservablePoint> ChartValues
 {
        get
        {
               var x = ((ILUTLibOneD)CurrentLUT).XValues;
               var y = ((ILUTLibOneD)CurrentLUT).YValues;

               for (int i = 0; i < x.Length; i++)
               {
                      chartValues.Add(new ObservablePoint { X = x[i], Y = y[i] });
               }
               return chartValues;
        }
        set
        {
               chartValues = value;
               OnPropertyChanged();
        }
 }

Solution

  • Your problem appears to be that you never update the binding for your CartesianChart, which is the SeriesCollection property. Look at your xaml, you have:

    <lvc:CartesianChart Series="{Binding SeriesCollection}"/>
    

    When you select a new CurrentLUT from the ComboBox, the setter updates only the lineSeries and then sends a PropertyChanged event for ONLY the CurrentLUT.

    set
    {
           currentLUT = value;
           lineSeries.Title = currentLUT.ToString();
           lineSeries.Values = chartValues;
           OnPropertyChanged(); // THIS ONLY UPDATES THE CurrentLUT BINDING!
    }
    

    You need it to also tell the CartesianChart to update itself, so maybe do something like this:

    set
    {
           currentLUT = value;
           lineSeries.Title = currentLUT.ToString();
           lineSeries.Values = chartValues;
           OnPropertyChanged();
    
           // Also update the CartesianChart
           OnPropertyChanged(nameof(this.SeriesCollection));
    }