2010-06-14 52 views
3

我目前在我的应用程序中重新编码条形图以利用WPF Toolkit中的Chart类。使用MVVM,我将图表中的ColumnSeriesItemsSource绑定到我的viewmodel上的一个属性。下面是相关的XAML:绑定更新将新闻系列添加到WPF工具包图表(而不是替换/更新系列)

<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的单个数据点)之前和之后的(现在与ScoreDistribution.ClassScores 3个数据点):

With a single data point

With 2 more data points added - note the original wide bar behind them

现在,我知道有其他的方法,我可以这样做(例如,改变原来的ScoreDistribution对象的内容,而不是完全取代它),但我不明白为什么它在其目前的FO脚麻R M。谁能帮忙?

回答

1

原来问题是由图表中更新的频率触发的,而不是整个系列被替换的事实;将数据绑定属性更改为ObservableCollection没有任何区别。

最后,我们更改了代码,以便在对底层数据进行更改之间包含延迟,并将这些更改反映到ViewModel的绑定集合属性中。尽管它的运行速度取决于应用程序的运行速度,但我们已经确定了最后一个基础数据更改和ViewModel属性更新之间的0.5秒延迟。这可以防止图表每0.5秒更新一次,它似乎能够完成这项工作。

在某些时候,我会实际浏览WPFToolkit代码,看看我能做些什么来解决它,但现在,这个解决方法值得注意。

0

你在做什么应该工作。它不表示WPF工具包的事实有一个错误。

WPF Toolkit在DataPointSeries上实现OnItemsSourceChanged()以检测替换ItemsSource并调用Refresh()的情况。 Refresh()具有删除所有数据点的代码(除已经动画化的数据点外),然后创建一组全新的DataPoints。很明显,代码中有一个错误。我看了一两分钟,但没有看到什么是错的。我将首先升级到最新的WPFToolkit版本。如果这样做不能解决问题,那么当ItemsSource被更改时,您可以通过DataPointSeries.Refresh()方法来查看发生了什么,以及它为什么不删除旧的DataPoint对象。

或者,正如您所观察到的那样,您可以通过更换集合内容而不是整个集合来解决该问题。

2

我有同样的问题。当更改DataPointSeries的ItemsSource时,它发生的事情是旧的DataPoints没有从图表中删除。

我在WPF工具包(DataPointSeries.cs)解决办法...

一个for代替LoadDataPoints()一个foreach循环,因为我们改变集合:

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

更改ifOnDataPointStateChanged()到:

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

这样数据点将是我马上删除。

编辑
我也不得不禁用数据点动画,描述here

+0

您的解决方法效果很好。我在工具箱的WinRT editon中遇到了同样的问题。谢谢。 – Bart 2012-11-24 12:13:31

+0

@freundblase我也有同样的问题。我已经下载了wpf工具包的源代码,但无法编译它,很多错误。你能否提供你正在使用的DLL。 – 2015-02-25 13:17:33

2

避免此问题的最简单方法是将系列ItemSource与IsAsync绑定为True。

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

这不适合我。也许我错过了什么。 – Buck 2013-09-19 06:44:22