2010-06-14 2 views
3

Je recode actuellement un graphique à barres dans mon application pour faire usage de la classe Chart dans le WPF Toolkit. À l'aide MVVM, je lie le ItemsSource d'un ColumnSeries dans mon graphique à une propriété sur mon modèle de vue. Voici le XAML pertinent:La mise à jour de liaison ajoute des séries de nouvelles au graphique WPF Toolkit (au lieu de remplacer/mettre à jour série)

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

Et la propriété sur le 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); 
     } 
    } 

Cependant, quand je mets à jour la propriété ScoreDistribution (en le plaçant à un nouvel objet ScoreDistribution), le graphique obtient un série supplémentaire (basée sur la nouvelle partition ScoreDistribution) ainsi que de conserver la série originale (basée sur la précédente ScoreDistribution).

Pour illustrer cela, voici quelques captures d'écran montrant le graphique avant une mise à jour (avec un seul point de données dans ScoreDistribution.ClassScores) et après (maintenant avec 3 points de données en ScoreDistribution.ClassScores):

With a single data point

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

maintenant, je me rends compte qu'il ya d'autres moyens que je pourrais faire cela (par exemple, modifier le contenu de l'objet ScoreDistribution d'origine plutôt que de le remplacer entièrement), mais je ne comprends pas pourquoi ça va mal dans son fo courant rm. Quelqu'un peut-il aider?

Répondre

1

Il s'avère que le problème a été déclenché par la fréquence des mises à jour dans le graphique, pas le fait que l'ensemble de la série a été remplacé; la modification de la propriété de databound à ObservableCollection n'a fait aucune différence. En fin de compte, nous avons modifié notre code pour inclure un délai entre les modifications apportées aux données sous-jacentes et les modifications reflétées dans la propriété de collection liée de ViewModel. Bien que cela dépende dans une certaine mesure de la vitesse de la machine sur laquelle s'exécute l'application, nous avons établi un délai de 0,5 seconde entre le dernier changement de données sous-jacent et la mise à jour de la propriété ViewModel. Cela empêche la mise à jour du graphique plus de tous les 0.5secs et il semble faire le travail. À un certain point, je vais passer en revue le code de WPFToolkit et voir ce que je peux faire pour le réparer, mais pour l'instant, cette solution de contournement mérite d'être notée.

0

Ce que vous faites devrait fonctionner. Le fait qu'il n'indique pas WPF Toolkit a un bug.

WPF Toolkit implémente OnItemsSourceChanged() sur DataPointSeries pour détecter le cas où vous remplacez ItemsSource et appelez Refresh(). Refresh() a du code pour supprimer tous les points de données (sauf ceux qui sont déjà en train de s'animer), puis créer un nouvel ensemble de DataPoints. Évidemment, ce code a un bug. J'ai regardé pendant une minute ou deux mais je n'ai pas vu ce qui n'allait pas. Je commencerais par mettre à jour vers la dernière version de WPFToolkit. Si cela ne le résout pas, vous pouvez passer par la méthode DataPointSeries.Refresh() lorsque ItemsSource est modifié pour voir ce qui s'y passe et pourquoi il ne supprime pas les anciens objets DataPoint. Ou, comme vous l'avez observé, vous pouvez contourner le problème en remplaçant simplement le contenu de la collection plutôt que la collection dans son ensemble.

2

J'ai eu le même problème.Lors de la modification de ItemsSource d'un DataPointSeries, il s'est produit que les anciens DataPoints n'ont pas été supprimés du graphique.

Ma solution dans la boîte à outils WPF (...) de DataPointSeries.cs

A for au lieu d'une boucle foreach dans LoadDataPoints(), parce que nous changeons la collection:

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

Modifier le if dans OnDataPointStateChanged() vers:

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

De cette façon, le DataPoint sera i Immédiatement retiré.

Modifier:
Je devais aussi désactiver l'animation DataPoint, décrit here.

+0

Votre solution de contournement fonctionne très bien. Je luttais avec le même bug dans WinRT editon de la boîte à outils. Merci. – Bart

+0

@freundblase J'ai aussi le même problème. J'ai téléchargé le code source de wpf toolkit mais je n'ai pas pu le compiler, beaucoup d'erreurs. Pouvez-vous s'il vous plaît fournir e la DLL que vous utilisez. –

2

La manière la plus simple d'éviter ce problème consiste à lier la série ItemSource avec IsAsync à True.

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

Cela n'a pas fonctionné pour moi. Peut-être que j'ai raté quelque chose. – Buck

Questions connexes