Обновление привязки добавляет серию новостей в диаграмму WPF Toolkit (вместо замены/обновления серии)

В настоящее время я перекодирую гистограмму в своем приложении, чтобы использовать класс Chart из WPF Toolkit. Используя MVVM, я привязываю ItemsSource из ColumnSeries на моей диаграмме к свойству в моей модели представления. Вот соответствующий XAML:

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

И свойство на модели представления:

// 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);
        }
    }

Однако, когда я обновляю свойство ScoreDistribution (устанавливая для него новый объект ScoreDistribution), диаграмма получает дополнительный ряд (на основе нового ScoreDistribution), а также сохраняет исходный ряд (на основе предыдущий ScoreDistribution).

Чтобы проиллюстрировать это, вот несколько снимков экрана, на которых показана диаграмма до обновления (с одной точкой данных в ScoreDistribution.ClassScores) и после него (теперь с 3 точками данных в ScoreDistribution.ClassScores):

С одной точкой данных

Добавлены еще 2 точки данных - обратите внимание на исходную широкую полосу позади них

Теперь я понимаю, что есть другие способы сделать это (например, изменить содержимое исходного объекта ScoreDistribution, а не заменить его полностью), но я не понимаю, почему это происходит неправильно в его текущей форме. Кто-нибудь может помочь?


person Mal Ross    schedule 14.06.2010    source источник


Ответы (4)


У меня такая же проблема. При изменении ItemsSource DataPointSeries случалось, что старые DataPoints не удалялись с графика.

Мой обходной путь в наборе инструментов WPF (DataPointSeries.cs)...

Цикл for вместо цикла foreach в LoadDataPoints(), потому что мы меняем коллекцию:

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

Измените if в OnDataPointStateChanged() на:

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

Таким образом, DataPoint будет немедленно удален.

Изменить:
Мне также пришлось отключить анимацию DataPoint, описанную здесь.

person freundblase    schedule 15.08.2012
comment
Ваш обходной путь отлично работает. Я боролся с той же ошибкой в ​​​​редакции WinRT набора инструментов. Спасибо. - person Bart; 24.11.2012
comment
@freundblase У меня тоже такая же проблема. Я загрузил исходный код инструментария wpf, но не смог его скомпилировать, много ошибок. Не могли бы вы предоставить e dll, который вы используете. - person mayank.karki; 25.02.2015

Самый простой способ избежать этой проблемы — привязать серию ItemSource с IsAsync к True.

ItemsSource="{Binding DataItems, IsAsync=True}"
person Zool    schedule 14.01.2013

Оказывается, проблема была вызвана частотой обновлений на диаграмме, а не тем фактом, что заменялся весь ряд; изменение свойства с привязкой к данным на ObservableCollection не имело значения.

В конце концов, мы изменили наш код, включив задержку между изменениями базовых данных и отражением этих изменений в связанном свойстве коллекции ViewModel. Хотя это в некоторой степени зависит от скорости компьютера, на котором работает приложение, мы установили задержку в 0,5 секунды между последним изменением базовых данных и обновлением свойства ViewModel. Это предотвращает обновление графика чаще, чем каждые 0,5 секунды, и, похоже, работает.

В какой-то момент я действительно пройдусь по коду WPFToolkit и посмотрю, что я могу сделать, чтобы исправить это, но пока стоит отметить этот обходной путь.

person Mal Ross    schedule 13.07.2010

То, что вы делаете, должно работать. Тот факт, что это не означает, что в WPF Toolkit есть ошибка.

WPF Toolkit реализует OnItemsSourceChanged() для DataPointSeries, чтобы обнаружить случай, когда вы заменяете ItemsSource и вызываете Refresh(). Refresh() имеет код для удаления всех точек данных (кроме тех, которые уже анимируются), а затем создает совершенно новый набор точек данных. Очевидно, что в этом коде есть ошибка. Я смотрел на него минуту или две, но не видел, что было не так. Я бы начал с обновления до последней версии WPFToolkit. Если это не поможет, вы можете пройтись по методу DataPointSeries.Refresh() при изменении ItemsSource, чтобы увидеть, что там происходит и почему старые объекты DataPoint не удаляются.

Или, как вы заметили, вы можете обойти ошибку, просто заменив содержимое коллекции, а не коллекцию в целом.

person Ray Burns    schedule 15.06.2010