WPF series visibility updates

Mar 26, 2014 at 3:18 PM
Hi,

I am trying to manipulate the PlotModel via MVVM. I have created a list of SeriesVisibility models that represent a Series (model, not WPF) with a Color and IsVisible properties. As soon as the property has changed, I pass on the property to the series model:
private void OnIsVisibleChanged()
{
    Series.IsVisible = IsVisible;
}
This does not update because the models do not implement INotifyPropertyChanged. I wanted to work around this problem with this method in a service:
public void UpdateSeriesVisibility()
{
    var plotModel = PlotModel;
    if (plotModel == null)
    {
        return;
    }

    var plotControl = plotModel.PlotControl as Plot;
    if (plotControl != null)
    {
        foreach (var viewSeries in plotControl.Series)
        {
            viewSeries.Visibility = viewSeries.InternalSeries.IsVisible ? Visibility.Visible : Visibility.Hidden;
        }
    }
}
Unfortunately the plotControl.Series is empty while PlotModel.Series and plotControl.ActualModel.Series are not empty.

Next thing I was trying is to UpdateData or InvalidatePlot, but this does not cause a re-render of the plot:
  • UpdateData(false and true)
  • InvalidatePlot(false and true)
  • InvalidArrange
Nothing seems to redraw. Only when I resize the window it actually redraws (without the unselected series).

Can you give some hints on how I can re-render the plot?
Mar 26, 2014 at 3:34 PM
I think I found something that works:
public void RenderPlot()
{
    var plotModel = PlotModel;
    if (plotModel == null)
    {
        return;
    }

    var plotControl = plotModel.PlotControl as Plot;
    if (plotControl != null)
    {
        plotControl.Dispatcher.BeginInvoke(() =>
        {
            plotControl.InvalidateFlag++;
        });
    }
}
I think there should be an easier way though.
Mar 26, 2014 at 6:24 PM
What version of OxyPlot you are using on what platform (net 3.5, 4 or 4.5)?
Mar 26, 2014 at 6:43 PM
WPF 4.0
Coordinator
Mar 26, 2014 at 7:52 PM
This sounds like a bug. PlotModel.InvalidatePlot should force the view to redraw.
It should not be necessary to call Plot.UpdateModel (private!) and PlotModel.Update (I think the last one should also be protected in some way).
Mar 26, 2014 at 7:53 PM
Yep, that's what I thought, but wanted to make sure. You are doing an awesome job so trying to help where I can. Why don't you implement INotifyPropertyChanged for your models. Are you afraid for a performance hit, or is there another reason?
Coordinator
Mar 26, 2014 at 8:17 PM
It's mostly because it is a lot of work to support it everywhere (e.g. we would need to subscribe to property changes on elements inside big collections). Remember changing most properties have the potential of a full invalidation of the plot view. Performance is another issue that must be considered (e.g. changing the y-coordinate of 100000 points at the same time). [KISS]
Mar 26, 2014 at 8:18 PM
I agree that you cannot listen to points (you haven't introduced the updateData bool in the invalidation methods. But I think you can listen to actual properties of axes and series. But as long as the UpdateModel or InvalidateModel redraw it, I am happy.

Remember that I found a workaround so you don't need to feel rushed in any way.