Précédent   Forum du club des développeurs et IT Pro > Dotnet > Développement Windows > Windows Presentation Foundation
Windows Presentation Foundation Forum d'entraide sur le développement d'applications Windows avec Windows Presentation Foundation
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 04/01/2013, 21h50   #1
Ub1quity
Invité de passage
 
Inscription : novembre 2009
Messages : 24
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 24
Points : 4
Points : 4
Par défaut WPF Toolkit et le Data Binding pour les graphiques

Bonsoir,

J'ai besoin d'afficher des données sur des graphiques avec le WPF Toolkit.

Je suis donc tombé sur ce tutoriel. On y voit la création des graphiques à l'initialisation de l'application.

Seulement voila, je souhaite faire en sorte que les données soient mises à jour suite à une interaction utilisateur. (Plus précisément, les données utilisées pour le graphique sont chargées depuis un fichier différent en fonction de la saisie utilisateur).

J'ai donc fait un essai, que voici :

XAML (j'ai uniquement gardé le LineChart et ajouté button1)
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<Window x:Class="WpfToolkitChart.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="462" Width="737" xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit">
    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Margin="0,-28,0,28">
        <Grid Height="921">
            <chartingToolkit:Chart  Name="lineChart" Title="Line Series Demo" VerticalAlignment="Top" Margin="24,21,26,0" Height="295" >
                <chartingToolkit:LineSeries  DependentValuePath="Value" IndependentValuePath="Key" ItemsSource="{Binding}" IsSelectionEnabled="True" Title="Serie"/>
            </chartingToolkit:Chart>
            <Button Content="Serie + 5" Height="54" HorizontalAlignment="Left" Margin="147,351,0,0" Name="button1" VerticalAlignment="Top" Width="159" Click="button1_Click" />
        </Grid>
    </ScrollViewer>
 
</Window>
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
namespace WpfToolkitChart
{
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
      showColumnChart();
    }
 
    private void showColumnChart()
    {
      List<KeyValuePair<string, int>> valueList = new List<KeyValuePair<string, int>>();
      valueList.Add(new KeyValuePair<string, int>("Developer", 100));
      valueList.Add(new KeyValuePair<string, int>("Misc", 20));
      valueList.Add(new KeyValuePair<string, int>("Tester", 50));
      valueList.Add(new KeyValuePair<string, int>("QA", 30));
      valueList.Add(new KeyValuePair<string, int>("Project Manager", 40));
 
      lineChart.DataContext = valueList;      
    }
 
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>();
        List<KeyValuePair<string, int>> serie = (List<KeyValuePair<string, int>>) lineChart.DataContext;
 
        foreach ( KeyValuePair<string, int> pair in serie )
        {
            list.Add(new KeyValuePair<string, int> (pair.Key, pair.Value + 5)); // simulation d'un changement de données
        }
        lineChart.DataContext = list;
    }
  }
}
Cette version marche tout à fait, mais j'aimerais savoir s'il n'existe pas une façon de faire du Data Binding dans le code XAML et non dans le côté C# (qui passe par un gestionnaire d'évènements). Qu'en est-il ? Je vous en remercie par avance.

PS : Je débute avec WPF mais pas C#
Ub1quity est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2013, 09h57   #2
GuruuMeditation
Expert Confirmé
 
Avatar de GuruuMeditation
 
Homme Olivier Matis
.Net Architect
Inscription : octobre 2010
Messages : 1 353
Détails du profil
Informations personnelles :
Nom : Homme Olivier Matis
Âge : 38
Localisation : Belgique

Informations professionnelles :
Activité : .Net Architect
Secteur : Conseil

Informations forums :
Inscription : octobre 2010
Messages : 1 353
Points : 2 870
Points : 2 870
Envoyer un message via MSN à GuruuMeditation
Tu va devoir passer par du C# pour les données. Mais tu peux changer ton code comme ceci :


Code C# :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using WpfApplication2.Annotations;
 
namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : INotifyPropertyChanged
    {
        private List<KeyValuePair<string, int>> _dataList;
 
        public List<KeyValuePair<string, int>> DataList
        {
            get { return _dataList; }
            set
            {
                if (Equals(value, _dataList)) return;
                _dataList = value;
                OnPropertyChanged("DataList");
            }
        }
 
        public MainWindow()
        {
            InitializeComponent();
            showColumnChart();
        }
 
        private void showColumnChart()
        {
            List<KeyValuePair<string, int>> valueList = new List<KeyValuePair<string, int>>();
            valueList.Add(new KeyValuePair<string, int>("Developer", 100));
            valueList.Add(new KeyValuePair<string, int>("Misc", 20));
            valueList.Add(new KeyValuePair<string, int>("Tester", 50));
            valueList.Add(new KeyValuePair<string, int>("QA", 30));
            valueList.Add(new KeyValuePair<string, int>("Project Manager", 40));
 
            DataContext = this;
        }
 
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            var list = new List<KeyValuePair<string, int>>();
 
            foreach (KeyValuePair<string, int> pair in DataList)
            {
                list.Add(new KeyValuePair<string, int>(pair.Key, pair.Value + 5)); // simulation d'un changement de données
            }
            DataList = list;
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

(Je l'ai fait sans tester, j'espère que je n'ai rien oublié)

Ce que j'ai fait : j'ai rajouté une propriété DataList.

J'ai implémenté INotifyPropertyChanged, qui est l'interface qui permet de dire au databinding que'une propriété à été changée et qu'il doit rafraichir.

Je mets le Datacontext de la page sur elle-meme

Dans le click, je crée une nouvelle liste et je la mets dans la variable DataList. Ca va envoyer une demande de rafraichissement au moteur de binding.

Dans le XAML, tu dois binder sur la propriété :
Code XAML :
1
2
 
<chartingToolkit:LineSeries  DependentValuePath="Value" IndependentValuePath="Key" ItemsSource="{Binding DataList}" IsSelectionEnabled="True" Title="Serie"/>

C'est plus dans la philosophie du databinding (et du MVVM) comme ça.

Tu peux encore aller plus loin et implémenter ta liste comme une ObservableCollection. Comme ça les changements dans ta liste seront immédiatement répercutée en binding.
__________________
Microsoft MVP : Visual C#

MCPD - Windows Phone Developer
MCPD - Windows Developer 4

http://www.guruumeditation.net

“If debugging is the process of removing bugs, then programming must be the process of putting them in.”
(Edsger W. Dijkstra)
GuruuMeditation est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2013, 22h26   #3
Ub1quity
Invité de passage
 
Inscription : novembre 2009
Messages : 24
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 24
Points : 4
Points : 4
Merci pour ta réponse, plus respectueuse du MVVM.

Malheureusement, je n'arrive pas à compiler à cause du [NotifyPropertyChangedInvocator], a priori une assembly ou un using manque (d'après Visual ...)
Visual me propose de générer la classe pour NotifyPropertyChangedInvocator ou de générer un nouveau type ...

J'ai bien rajouté le
Code :
using System.ComponentModel;
mais je n'ai pas pu rajouter
Code :
using WpfToolkitChart.Applications// Comme j'utilise le namespace WpfToolkitChart
à l'instar du
Code :
WpfApplication2.Applications
que tu utilises.

Saurais-tu d'où provient mon problème avec le NotifyPropertyChangedInvocator ?

___
Edit : Quand je supprime purement et simplement cette ligne, à l'exécution, le graphique est vite et quand je clique sur le bouton, ça plante dans la boucle foreach car DataList n'est pas instanciée (null donc).
Ub1quity est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/01/2013, 09h36   #4
GuruuMeditation
Expert Confirmé
 
Avatar de GuruuMeditation
 
Homme Olivier Matis
.Net Architect
Inscription : octobre 2010
Messages : 1 353
Détails du profil
Informations personnelles :
Nom : Homme Olivier Matis
Âge : 38
Localisation : Belgique

Informations professionnelles :
Activité : .Net Architect
Secteur : Conseil

Informations forums :
Inscription : octobre 2010
Messages : 1 353
Points : 2 870
Points : 2 870
Envoyer un message via MSN à GuruuMeditation
Tu peux virer le [NotifyPropertyChangedInvocator], c'est une extension de Resharper, un plugin pour Visual Studio (que je conseille, ça aide vraiment). J'ai oublié de l'enlever, désolé.
__________________
Microsoft MVP : Visual C#

MCPD - Windows Phone Developer
MCPD - Windows Developer 4

http://www.guruumeditation.net

“If debugging is the process of removing bugs, then programming must be the process of putting them in.”
(Edsger W. Dijkstra)
GuruuMeditation est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/01/2013, 19h46   #5
Ub1quity
Invité de passage
 
Inscription : novembre 2009
Messages : 24
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 24
Points : 4
Points : 4
Merci ! J'ai également ajouté une ligne dans la méthode qui créé valuelist

Code :
1
2
3
4
5
6
7
8
9
10
11
12
        private void showColumnChart()
        {
            List<KeyValuePair<string, int>> valueList = new List<KeyValuePair<string, int>>();
            valueList.Add(new KeyValuePair<string, int>("Developer", 100));
            valueList.Add(new KeyValuePair<string, int>("Misc", 20));
            valueList.Add(new KeyValuePair<string, int>("Tester", 50));
            valueList.Add(new KeyValuePair<string, int>("QA", 30));
            valueList.Add(new KeyValuePair<string, int>("Project Manager", 40));
 
            DataList = valueList; //Sinon j'avais une erreur
            DataContext = this;
        }
Pour Resharper, pour collaborer avec des gens qui ne le possède pas, on doit nécessairement retirer à la main les lignes comme [NotifyPropertyChangedInvocator] ?

Et c'est le fait de mettre le DataContext sur la fenêtre elle même qui tend à respecter le MVVM ?
Ub1quity est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2013, 20h25   #6
GuruuMeditation
Expert Confirmé
 
Avatar de GuruuMeditation
 
Homme Olivier Matis
.Net Architect
Inscription : octobre 2010
Messages : 1 353
Détails du profil
Informations personnelles :
Nom : Homme Olivier Matis
Âge : 38
Localisation : Belgique

Informations professionnelles :
Activité : .Net Architect
Secteur : Conseil

Informations forums :
Inscription : octobre 2010
Messages : 1 353
Points : 2 870
Points : 2 870
Envoyer un message via MSN à GuruuMeditation
NotifyPropertyChangedInvocator n'est pas nécessaire quand tu as resharper non plus. C'est juste pour lui dire que c'est cette méthode qui implémente INotifyPropertyChange. Avec ça, tu peux dire à Resharper de la rajouter automatiquement pour toutes les propriétés. C'est juste pour automatiqer certaines tâches redondantes. (Au cas ou tu es curieux : http://blogs.jetbrains.com/dotnet/20...n-resharper-7/ )

Quand je parlais d'esprit MVVM, c'est l'idée de faire des propriétés, d’implémenter INotifipropertyChanged et de binder sur ces propriétés. Et non pas le faire "à la main" comme tu le faisais (en mettant le datacontext du chart dans le code)
__________________
Microsoft MVP : Visual C#

MCPD - Windows Phone Developer
MCPD - Windows Developer 4

http://www.guruumeditation.net

“If debugging is the process of removing bugs, then programming must be the process of putting them in.”
(Edsger W. Dijkstra)
GuruuMeditation est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2013, 11h35   #7
Ub1quity
Invité de passage
 
Inscription : novembre 2009
Messages : 24
Détails du profil
Informations forums :
Inscription : novembre 2009
Messages : 24
Points : 4
Points : 4
Merci pour tes réponses
Ub1quity est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 10h52.


 
 
 
 
Partenaires

Hébergement Web