IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

[C#] Binding datagridview depuis une datatable dynamiquement


Sujet :

Windows Forms

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    391
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 391
    Points : 347
    Points
    347
    Par défaut [C#] Binding datagridview depuis une datatable dynamiquement
    Bonjour


    Dans une appli winform j'ai une datagridview dont la datasource est une datatable.
    Cette datatable est alimentée par des threadPool et je souhaiterais effectuer un affichage dynamique de mes données.

    Pour cela j'ai ajouté un timer a ma winform et je met la datasource à null puis de nouveau a ma datatable .
    (la litterature semble dire que si on ajoute un row sur une datatable binder sur un datagridview, le datagridview s'update mais pas dans mon cas)

    Le résultat est bien un update dynamique mais j'ai sur un PC client une erreur windows doit arreter cette application et cherche une solution.

    Si j’arrête le timer et que je refresh uniquement a la fin des ajouts du datatable pas de probleme.
    J'ai essayer de try catch cette fonction sur ce PC sans résultat (la fenêtre arrive windows doit ... mais pas mon exception)

    1 - comment faire un update dynamique d'une datagridview a partir d'un datatable en evolution a partir de threadpool

    2 - comment savoir ce qui provoque l'erreur sur le PC , n 'ayant pas le pb sur mon PC de dev qui est presque en même configuration.

    3 - pourquoi le try catch ne marche PAS?

    Cordialement

  2. #2
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    la litterature semble dire que si on ajoute un row sur une datatable binder sur un datagridview, le datagridview s'update mais pas dans mon cas
    Usuellement, ça marche sans avoir besoin de timer, de DataSource à null, ni d'aucun refresh.

    Le problème doit venir de l'utilisation de threads.


    On pourrait essayer ceci :
    • dans les threads, ajouter les rows à une datable intermédiaire (non bindée),
    • mettre un timer dans la winform,
    • sur l'event du timer, transférer les rows de la table intermédiaire dans la DataTable bindée.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par ricky78 Voir le message
    1 - comment faire un update dynamique d'une datagridview a partir d'un datatable en evolution a partir de threadpool
    Un aspect important du développement Windows est que seul le thread de l'interface graphique (UI) peut agir sur l'interface graphique. Quand on modifie un DataTable sur lequel un DataGridView est bindé, ça modifie (indirectement) l'interface graphique. Il faut donc passer par la méthode Invoke pour effectuer les modifications sur la DataTable. Tu trouveras pas mal d'exemple en cherchant "Invoke" sur le forum, ou dans la documentation de la méthode

    Citation Envoyé par ricky78 Voir le message
    2 - comment savoir ce qui provoque l'erreur sur le PC , n 'ayant pas le pb sur mon PC de dev qui est presque en même configuration.
    En général on intercepte l'erreur avec try/catch, et on affiche l'erreur avec un MessageBox ou alors on l'écrit dans un log... ce qui nous amène à la question suivante :

    Citation Envoyé par ricky78 Voir le message
    3 - pourquoi le try catch ne marche PAS?
    Try/catch marche très bien... qu'est-ce qui te fait croire que ça ne marche pas ? Tu ne l'as peut-être pas utilisé correctement ? Peux-tu montrer la partie du code qui est concernée ?

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    391
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 391
    Points : 347
    Points
    347
    Par défaut
    bonjour

    Merci tomlev pour ta réponse

    pour le 1 : Je vais recoder en utilisant les invoke, je pensait que je devais le faire qu' au niveau des controles et pas des datatables.

    pour le 2 : Je veux dire que le try/catch ne me leve pas d'exception en particulier pour cette erreur a savoir que sur mon Pc de dev je n'ai pas d'erreur et sur un PC W7, .net 4.0 j'ai l'erreur windows doit arrêter cette application sans avoir levé l'exception.

    voici le code concerné;
    PS : j'ai fait un essai en créant une vue sans succès

    Cordialement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
     
     try
                {                  
                    if ((selectedReader >= 0) & (selectedReader < localDeviceArray.Length))  //reader local
                    {
     
                        if (tabControlInventory.SelectedIndex == 0)
                        {
                            dataGridViewAll.Invoke((MethodInvoker)delegate
                               {
                                   dataGridViewAll.DataSource = null;
                                   //dataGridViewAll.DataSource = localDeviceArray[selectedReader].currentInventory.dtTagAll.DefaultView;                                                    
                                   DataView view = new DataView(localDeviceArray[selectedReader].currentInventory.dtTagAll);
                                   dataGridViewAll.DataSource = view;
     
                               });
                        }
     
                        if (tabControlInventory.SelectedIndex == 1)
                        {
                            dataGridViewPresent.Invoke((MethodInvoker)delegate
                            {
                                dataGridViewPresent.DataSource = null;
                                // dataGridViewPresent.DataSource = localDeviceArray[selectedReader].currentInventory.dtTagPresent.DefaultView;
                                DataView view = new DataView(localDeviceArray[selectedReader].currentInventory.dtTagPresent);
                                dataGridViewPresent.DataSource = view;
     
                            });
                        }
                        if (tabControlInventory.SelectedIndex == 2)
                        {
                            dataGridViewAdded.Invoke((MethodInvoker)delegate
                            {
                                dataGridViewAdded.DataSource = null;
                                //dataGridViewAdded.DataSource = localDeviceArray[selectedReader].currentInventory.dtTagAdded.DefaultView;
                                DataView view = new DataView(localDeviceArray[selectedReader].currentInventory.dtTagAdded);
                                dataGridViewAdded.DataSource = view;
     
                            });
                        }
     
                        if (tabControlInventory.SelectedIndex == 3)
                        {
                            dataGridViewRemove.Invoke((MethodInvoker)delegate
                            {
                                dataGridViewRemove.DataSource = null;
                                //dataGridViewRemove.DataSource = localDeviceArray[selectedReader].currentInventory.dtTagRemove.DefaultView;
                                DataView view = new DataView(localDeviceArray[selectedReader].currentInventory.dtTagRemove);
                                dataGridViewRemove.DataSource = view;
     
                            });
                        }
     
                        int nbTagGridAll = dataGridViewAll.Rows.Count;
                        int nbTagGridPresent = dataGridViewPresent.Rows.Count;
                        int nbTagGridAdded = dataGridViewAdded.Rows.Count;
                        int nbTagGridRemove = dataGridViewRemove.Rows.Count;
     
                        if (nbTagGridAll < 0) nbTagGridAll = 0;
                        if (nbTagGridPresent < 0) nbTagGridPresent = 0;
                        if (nbTagGridAdded < 0) nbTagGridAdded = 0;
                        if (nbTagGridRemove < 0) nbTagGridRemove = 0;
     
                        tabControlInventory.Invoke((MethodInvoker)delegate
                        {
                            tabControlInventory.TabPages[0].Text = "All ( " + nbTagGridAll.ToString() + ")";
                            tabControlInventory.TabPages[1].Text = "Initialy Present ( " + nbTagGridPresent.ToString() + ")";
                            tabControlInventory.TabPages[2].Text = "Added ( " + nbTagGridAdded.ToString() + ")";
                            tabControlInventory.TabPages[3].Text = "Remove ( " + nbTagGridRemove.ToString() + ")";
                        });
     
                        if ((bFinishUpdateTabControl) &&
                          (nbTagGridAll == localDeviceArray[selectedReader].currentInventory.nbTagAll) &&
                          (nbTagGridPresent == localDeviceArray[selectedReader].currentInventory.nbTagPresent) &&
                          (nbTagGridAdded == localDeviceArray[selectedReader].currentInventory.nbTagAdded) &&
                          (nbTagGridRemove == localDeviceArray[selectedReader].currentInventory.nbTagRemoved))
                        {
                            Invoke((MethodInvoker)delegate { timerTabControlRefresh.Enabled = false; });
                        }
                        else
                            Invoke((MethodInvoker)delegate { timerTabControlRefresh.Enabled = true; });
                    }
                    else
                    {
                        if (tabControlInventory.SelectedIndex == 0)
                        {
                            dataGridViewAll.Invoke((MethodInvoker)delegate
                            {
                                dataGridViewAll.DataSource = null;
                               // dataGridViewAll.DataSource = networkDeviceArray[selectedReader - localDeviceArray.Length].currentInventory.dtTagAll.DefaultView;                                                     
                                DataView view = new DataView(networkDeviceArray[selectedReader - localDeviceArray.Length].currentInventory.dtTagAll);
                                dataGridViewAll.DataSource = view;
     
                            });
                        }
     
                        if (tabControlInventory.SelectedIndex == 1)
                        {
                            dataGridViewPresent.Invoke((MethodInvoker)delegate
                            {
                                dataGridViewPresent.DataSource = null;
                                //dataGridViewPresent.DataSource = networkDeviceArray[selectedReader - localDeviceArray.Length].currentInventory.dtTagPresent.DefaultView;
                                DataView view = new DataView(networkDeviceArray[selectedReader - localDeviceArray.Length].currentInventory.dtTagPresent);
                                dataGridViewPresent.DataSource = view;
     
                            });
                        }
                        if (tabControlInventory.SelectedIndex == 2)
                        {
                            dataGridViewAdded.Invoke((MethodInvoker)delegate
                            {
                                dataGridViewAdded.DataSource = null;
                               // dataGridViewAdded.DataSource = networkDeviceArray[selectedReader - localDeviceArray.Length].currentInventory.dtTagAdded.DefaultView;
                                DataView view = new DataView(networkDeviceArray[selectedReader - localDeviceArray.Length].currentInventory.dtTagAdded);
                                dataGridViewAdded.DataSource = view;
     
                            });
                        }
                        if (tabControlInventory.SelectedIndex == 3)
                        {
                            dataGridViewRemove.Invoke((MethodInvoker)delegate
                            {
                                dataGridViewRemove.DataSource = null;
                               // dataGridViewRemove.DataSource = networkDeviceArray[selectedReader - localDeviceArray.Length].currentInventory.dtTagRemove.DefaultView;
                                DataView view = new DataView(networkDeviceArray[selectedReader - localDeviceArray.Length].currentInventory.dtTagRemove);
                                dataGridViewRemove.DataSource = view;
     
                            });
                        }
     
                        int nbTagGridAll = dataGridViewAll.Rows.Count;
                        int nbTagGridPresent = dataGridViewPresent.Rows.Count;
                        int nbTagGridAdded = dataGridViewAdded.Rows.Count;
                        int nbTagGridRemove = dataGridViewRemove.Rows.Count;
     
                        if (nbTagGridAll < 0) nbTagGridAll = 0;
                        if (nbTagGridPresent < 0) nbTagGridPresent = 0;
                        if (nbTagGridAdded < 0) nbTagGridAdded = 0;
                        if (nbTagGridRemove < 0) nbTagGridRemove = 0;
     
                        tabControlInventory.Invoke((MethodInvoker)delegate
                        {
                            tabControlInventory.TabPages[0].Text = "All ( " + nbTagGridAll.ToString() + ")";
                            tabControlInventory.TabPages[1].Text = "Initialy Present ( " + nbTagGridPresent.ToString() + ")";
                            tabControlInventory.TabPages[2].Text = "Added ( " + nbTagGridAdded.ToString() + ")";
                            tabControlInventory.TabPages[3].Text = "Remove ( " + nbTagGridRemove.ToString() + ")";
                        });
     
                        Application.DoEvents();
     
                    }
                }
                catch(Exception exp)
                {
                    ErrorMessage.ExceptionMessageBox.Show(exp);
                }
            }

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    391
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 391
    Points : 347
    Points
    347
    Par défaut
    Bonjour

    Apres un rapide coup d'oeil a la datatable, il n y a pas d'Invoke disponible?

    Je vais essayer donc de partir sur la méthode de graffito avec une table intermediare.

    cordialement

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Ben là quasiment tout le code que tu as posté manipule l'UI... donc il faudrait exécuter toute la méthode dans le thread de l'UI, ce qui fait que ça n'a plus de sens de lancer un nouveau thread. Il faudrait que tu restructures le code pour mieux séparer l'accès aux données et la manipulation de l'UI

    Pour ce qui est de l'exception, le problème est le même : pour appeler une MessageBox, il faut être sur le thread de l'UI, sinon ça pète... Essaie d'écrire l'exception dans un fichier log pour voir si ça te donne plus d'infos

    Citation Envoyé par ricky78 Voir le message
    Apres un rapide coup d'oeil a la datatable, il n y a pas d'Invoke disponible?
    Non, seulement sur les contrôles

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    391
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 391
    Points : 347
    Points
    347
    Par défaut
    bonjour

    Je n'ai pas été assez clair!

    Ce code est lance a a partir d'un timer de 1 second dans le thread principal.
    Les thread secondaires sont juste la pour acceder a la DB , et ajouter des rows aux datatables en fonction des resultats de requete

    voila le code

    Dans le thead principal
    Appel par exemple pour updater une des table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
     DtAndTagClass DtAndTagAll = new DtAndTagClass(localDeviceArray[nIndex].currentInventory.dtTagAll, args.Message, db);
                                ThreadPool.QueueUserWorkItem(new WaitCallback(AddTagToDt), (object)DtAndTagAll);
    El la classe associer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     public class DtAndTagClass
        {
            public DataTable dt;
            public string tagUID;
            public DBClass db;
            public DtAndTagClass(DataTable dt, string tagUID,DBClass db)
            {
                this.dt = dt;
                this.tagUID = tagUID;
                this.db = db;
            }
        }
    le code du thread

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
     private static void AddTagToDt(object obj)
            {
     
                DtAndTagClass clToProcess = (DtAndTagClass)obj;
     
                string[] productInfo = clToProcess.db.RecoverProductInfo(clToProcess.tagUID);
     
     
                if (productInfo == null)
     
                  clToProcess.dt.Rows.Add(clToProcess.tagUID, " Unreferenced ", " ");
                else
                  clToProcess.dt.Rows.Add(productInfo[0], productInfo[1], productInfo[2]);
            }

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    OK bah dans ce cas il suffit que tu fasses la modif de la DataTable dans un Invoke:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     private static void AddTagToDt(object obj)
            {
     
                DtAndTagClass clToProcess = (DtAndTagClass)obj;
     
                string[] productInfo = clToProcess.db.RecoverProductInfo(clToProcess.tagUID);
     
     
                theForm.Invoke(new MethodInvoker(() =>
                {
                    if (productInfo == null) 
                      clToProcess.dt.Rows.Add(clToProcess.tagUID, " Unreferenced ", " ");
                    else
                      clToProcess.dt.Rows.Add(productInfo[0], productInfo[1], productInfo[2]);
                });
            }
    (theForm étant une référence à la Form)

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    391
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 391
    Points : 347
    Points
    347
    Par défaut
    bonjour

    Merci ,

    je vais essayer cela en ajoutant a ma classe DtAndTagClass ,la form.
    Je vous tient au courant.

    Cordialement

Discussions similaires

  1. Réponses: 7
    Dernier message: 28/01/2011, 16h45
  2. Réponses: 6
    Dernier message: 16/09/2010, 23h04
  3. remplir un datagridview depuis une classe
    Par thor76160 dans le forum C#
    Réponses: 2
    Dernier message: 03/04/2010, 14h00
  4. Une datatable dynamique
    Par Gibou dans le forum Accès aux données
    Réponses: 4
    Dernier message: 19/08/2009, 16h29
  5. Réponses: 5
    Dernier message: 23/03/2008, 08h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo