Binding update adds news series to WPF Toolkit chart (instead of replacing/updating series)

大兔子大兔子 提交于 2020-02-20 10:25:08

问题


I'm currently recoding a bar chart in my app to make use of the Chart class in the WPF Toolkit. Using MVVM, I'm binding the ItemsSource of a ColumnSeries in my chart to a property on my viewmodel. Here's the relevant XAML:

<charting:Chart>
  <charting:ColumnSeries ItemsSource="{Binding ScoreDistribution.ClassScores}"
                         IndependentValuePath="ClassName" DependentValuePath="Score"/>
</charting:Chart>

And the property on the viewmodel:

// NB: viewmodel derived from Josh Smith's BindableObject
public class ExamResultsViewModel : BindableObject
{
    // ...

    private ScoreDistributionByClass _scoreDistribution;
    public ScoreDistributionByClass ScoreDistribution
    {
        get
        {
            return _scoreDistribution;
        }
        set
        {
            if (_scoreDistribution == value)
            {
                return;
            }

            _scoreDistribution = value;

            RaisePropertyChanged(() => ScoreDistribution);
        }
    }

However, when I update the ScoreDistribution property (by setting it to a new ScoreDistribution object), the chart gets an additional series (based on the new ScoreDistribution) as well as keeping the original series (based on the previous ScoreDistribution).

To illustrate this, here are a couple of screenshots showing the chart before an update (with a single data point in ScoreDistribution.ClassScores) and after it (now with 3 data points in ScoreDistribution.ClassScores):

Now, I realise there are other ways I could be doing this (e.g. changing the contents of the original ScoreDistribution object rather than replacing it entirely), but I don't understand why it's going wrong in its current form. Can anyone help?


回答1:


I had the same problem. When changing the ItemsSource of a DataPointSeries it happened that old DataPoints were not removed from the chart.

My workaround in the WPF Toolkit (DataPointSeries.cs)...

A for instead of a foreach loop in LoadDataPoints(), because we change the collection:

for (int i = oldItems.Count - 1; i >= 0; i--)

Change the if in OnDataPointStateChanged() to:

if (dataPoint.State == DataPointState.Hidden || dataPoint.State == DataPointState.PendingRemoval)

This way the DataPoint will be immediately removed.

Edit:
I also had to disable the DataPoint animation, described here.




回答2:


The most simple way to avoid this problem is to bind the serie ItemSource with IsAsync to True.

ItemsSource="{Binding DataItems, IsAsync=True}"



回答3:


Turns out the problem was triggered by the frequency of updates in the chart, not the fact that the entire series was being replaced; changing the databound property to an ObservableCollection made no difference.

In the end, we changed our code to include a delay between changes to the underlying data and those changes being reflected in the ViewModel's bound collection property. While it does depend to an extent on the speed of the machine on which the app is running, we've settled on a 0.5sec delay between the last underlying data change and the ViewModel property updating. This prevents the chart being updated more than every 0.5secs and it seems to do the job.

At some point, I'll actually go through the WPFToolkit code and see what I can do to fix it, but for now, this workaround's worth noting.




回答4:


What you are doing ought to work. The fact that it doesn't indicates WPF Toolkit has a bug.

WPF Toolkit implements OnItemsSourceChanged() on DataPointSeries to detect the case where you replace ItemsSource and call Refresh(). Refresh() has code to remove all data points (except ones that are already animating away) and then create a whole new set of DataPoints. Obviously that code has a bug in it. I looked for a minute or two at it but didn't see what was wrong. I would start by upgrading to the latest WPFToolkit release. If that doesn't fix it, you might step through the DataPointSeries.Refresh() method when the ItemsSource is changed to see what is happening there and why it isn't removing the old DataPoint objects.

Or, as you observed, you could work around the bug by just replacing the collection content instead of the collection as a whole.



来源:https://stackoverflow.com/questions/3039141/binding-update-adds-news-series-to-wpf-toolkit-chart-instead-of-replacing-updat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!