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 :

Modifier/Ajouter/Supprimer des données directements dans un datagridview


Sujet :

Windows Forms

  1. #1
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    397
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 397
    Points : 130
    Points
    130
    Par défaut Modifier/Ajouter/Supprimer des données directements dans un datagridview
    Bonsoir,

    Est-ce que quelqu'un aurait un tuto/bonne explication sur comment faire la modifications, suppression ou ajout de cellules dans un datagridview?

    Je suis actuellement en train de voir comment cela ce fait mais je n'arrive pas à trouver de l'info dessus (probablement parce que je ne sais pas quelle propriété fait ce dont je veux)

    Merci bien et bonne soirée

    L.

  2. #2
    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
    La méthode "crade" pour modifier une valeur d'une cellule :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    DataGridView.Rows[indexLigne]["nomColonne"].Value = laValeur;
    // ou encore:
    dataGridView1.Rows[indexLigne][indexColonne].Value = laValeur;
    Tu ne peux pas ajouter ou supprimer une cellule individuelle, seulement une ligne entière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // ajout
    int indexLigne = dataGridView1.Rows.Add();
     
    // suppression
    dataGridView1.Rows.RemoveAt(indexLigne);
    La méthode propre, c'est d'utiliser le DataBinding. Tu associes à ton DataGridView une source de données (propriété DataSource), qui peut être par exemple une DataTable (le plus simple) ou une liste d'objets. Pour modifier le contenu du DataGridView, tu modifies la source de données, qui notifie le DataGridView pour qu'il se mette à jour.

    Pour une DataTable, ça marche tout seul : tu modifies les valeurs, tu ajoutes/supprimes des lignes de la table, et la grille se met à jour en fonction de ça.

    Pour une liste d'objets c'est un peu plus complexe :
    - les objets de la liste doivent implémenter INotifyPropertyChanged pour déclencher un évènement quand une valeur de propriété change (sinon le DataGridView ne pourra pas le savoir)
    - la liste elle-même doit implémenter IBindingList, pour déclencher un évènement quand la liste change (ajout ou suppression d'éléments). Le plus simple est d'utiliser la classe BindingList<T> qui gère déjà tout ça

    A noter : le databinding fonctionne dans les 2 sens. Si le DataGridView est éditable, les modifications faites par l'utilisateur sont répercutées sur la source de données.

  3. #3
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    397
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 397
    Points : 130
    Points
    130
    Par défaut
    Ce que tu propose marche quand l'utilisateurs rentre directement les données dans la DataGridView?

  4. #4
    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 Leelith Voir le message
    Ce que tu propose marche quand l'utilisateurs rentre directement les données dans la DataGridView?
    C'est à dire ? J'en ai parlé dans le dernier paragraphe de ma réponse, qu'est-ce qui te manque ?

  5. #5
    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
    Ce que tu propose marche quand l'utilisateurs rentre directement les données dans la DataGridView?
    Honnetement, abandonne cette idée.

    Sauf cas particuliers très simple, saisir directement dans le DataGridView conduit à toute une série de problèmes dont je n'ai pu me dépatouiller (après 6 semaines de travail et 2 versions de ma bibli à la poubelle ) qu'en créant des boutons d'ajout/suppression/modification et en faisant la saisie dans un panel présentant un seul enregistrement.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  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
    Citation Envoyé par Graffito Voir le message
    Honnetement, abandonne cette idée.

    Sauf cas particuliers très simple, saisir directement dans le DataGridView conduit à toute une série de problèmes dont je n'ai pu me dépatouiller (après 6 semaines de travail et 2 versions de ma bibli à la poubelle ) qu'en créant des boutons d'ajout/suppression/modification et en faisant la saisie dans un panel présentant un seul enregistrement.
    Je ne suis absolument pas d'accord... J'ai travaillé pendant deux ans sur une appli qui faisait un usage massif du DataGridView, la saisie se faisant directement dans la grille. Ca a toujours fonctionné sans problème, aussi bien dans des cas simples que pour des scénarios très complexes.

    Le contrôle DataGridView est prévu pour ce genre de choses, si tu n'as pas réussi à t'en servir, c'est que tu t'y es mal pris... Evite donc de rejeter la faute sur ce malheureux contrôle qui n'a rien demandé et rend de grands services à des milliers de développeurs

  7. #7
    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
    si tu n'as pas réussi à t'en servir, c'est que tu t'y es mal pris...
    Probablement, c'était l'un de mes premiers pas en C#.
    Mais, c''est quand même un retour d'expérience.

    Une bonne partie des problèmes vient du fait que le dataGridView ne permet pas de savoir de façon naturelle que la modification d'une cellule ou la création d'un nouvel enregistrement est validée et reportée dans le DataTable bindé.

    D'autre part, il m'a été quasiment impossible de synchoniser dans tous les cas de figure la saisie standard avec un bouton d'ajout (pour remplir la dernière ligne vide avec des valeurs par défaut) et un bouton de suppression.

    Et, je ne suis pas vraiment confiant sur la cohérence du comportement en saisie lorsqu'on utilise des filtres.

    Cela dit, je m'en sert aussi massivement avec un composant en bibli à base de DataGridView avec en particulier des fonctions de recherche, de tri multicolonne, de filtre multi-critère, d'impression et de remplacement automatique.

    Donc, un composant puissant, mais j'ai pas réussi à le maîtriser pour la saisie à l'interieur même du dgv .
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 38
    Points : 39
    Points
    39
    Par défaut
    Citation Envoyé par Graffito Voir le message
    Une bonne partie des problèmes vient du fait que le dataGridView ne permet pas de savoir de façon naturelle que la modification d'une cellule ou la création d'un nouvel enregistrement est validée et reportée dans le DataTable bindé.
    WCF RIA Services règle très bien cette problématique et tout est géré nativement (y compris la validation des données en conformité avec les restrictions sur la base de données -> si un string 20 est attendu, tu ne pourras saisir qu'un string 20)

  9. #9
    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 stivideo Voir le message
    WCF RIA Services règle très bien cette problématique et tout est géré nativement (y compris la validation des données en conformité avec les restrictions sur la base de données -> si un string 20 est attendu, tu ne pourras saisir qu'un string 20)
    alors là je vois pas le rapport avec la choucroute
    WCF RIA Services est un composant de communication, ça n'a strictement aucun lien avec le DataGridView qui sert à afficher et éditer des données...

  10. #10
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    397
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 397
    Points : 130
    Points
    130
    Par défaut
    Citation Envoyé par tomlev Voir le message
    C'est à dire ? J'en ai parlé dans le dernier paragraphe de ma réponse, qu'est-ce qui te manque ?
    En faite, je n'ai pas trop d'idée de que faire lorsqu'un utilisateur rentre une nouvelle ligne ou en modifie/supprime une.

    Qu'elle est la méthode à utiliser dans le dataset pour faire le traitement nécessaire déclenché par l'action de l'utilisateur notamment?
    Parce que conscernant la mise à jour ça n'est pas un problème, il suffit de prendre les données modifiée du dataset et les répercuter dans mes fichiers XML (dailleurs est-ce qu'il y a un moyen de faire ça spécifique aux fichiers XML?)

  11. #11
    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
    Qu'elle est la méthode à utiliser dans le dataset pour faire le traitement nécessaire déclenché par l'action de l'utilisateur notamment?
    Les event pertinents sont entre autres :
    • RowsAdded
    • RowsRemoved
    • RowValidated
    • RowValidating
    La DataTable à laquelle le DataGridView est bindé, est mise à jour automatiquement par l'édition du DataGridView (enfin quand la modification est "validée" ...).

    Si on veut metttre à jour la DataBase associée, on pourra utiliser DataAdater.Update() et DataTable.AcceptChanges().
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  12. #12
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    397
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 397
    Points : 130
    Points
    130
    Par défaut
    bon moi en l'occurence je n'ai pas associé mon fichier directement au datasource.

    J'ai créé une datatable dans laquelle je rempli manuellement depuis mon fichier XML (il a une structure particulière).

    Donc du coup je dois faire cela manuellement alors dans chaque évènement que tu as suggeré?

  13. #13
    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
    Donc du coup je dois faire cela manuellement alors dans chaque évènement que tu as suggeré?
    Non, la DataTable est mise à jour automatiquement à partir de l'édition du DataGridView. Tu n'as donc plus qu'à la retransférer en XML dès que tu le souhaites, en fin de programme par exemple, et en faisant attention à la cellule en cours d'édition (pas encore "validée").

    Ce qui peut être plus compliqué est la gestion des procédures de contrôles pour signaler des erreurs de saisie, comme des valeurs hors de leur intervalle de validité, des inconsistances entre les valeurs de 2 champs ou avec un autre enregistrement.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  14. #14
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    397
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 397
    Points : 130
    Points
    130
    Par défaut
    Ok.

    Par contre j'ai un petit soucis car les méthodes RowDeleted s'actionne quand je cache des colonnes. Est-ce normale?

  15. #15
    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 Leelith Voir le message
    Par contre j'ai un petit soucis car les méthodes RowDeleted s'actionne quand je cache des colonnes. Est-ce normale?
    Euh, non, pas vraiment

  16. #16
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    397
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 397
    Points : 130
    Points
    130
    Par défaut
    En faite, c'est quand les deux dernières lignes du code suivants sont executées qu'ils déclenche l'événement RowDeleted:

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    dgvRates.DataSource = XMLQueriesRepository.LoadRatesXMLFileIntoDataSet().Tables[0];
                MessageBox.Show("Hiding id column");
                dgvRates.Columns["Id"].Visible = false;
                MessageBox.Show("Columns size");
                dgvRates.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
                MessageBox.Show("Sorting columns ");
                dgvRates.Sort(dgvRates.Columns["Grade"], ListSortDirection.Ascending);
                MessageBox.Show("LoadAreas finished");

    Pour être précis, l'évènement se déclenche 3 fois :s

    En fait il fait correctement jusqu'à la fin. Je fois le LoadAreas qui s'affiche, puis il fait 3 row deleted, puis 4-5 row added en alternance:1 added, 1 deleted, 1 added, 1 deleted, 1 added, 1 deleted, 1 added, 1 added.

    Du coup je ne comprend vraiment pas pourquoi il me fait ça :s

    Une petite idée?

    Merci bien et bon dimanche

    L.

  17. #17
    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 Leelith Voir le message
    Pas une petite idée? :s
    Nope... jamais vu ça

  18. #18
    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
    J'ai trouvé ceci sur le web (réponse du support msdn), qui ressemble à ton problème :
    I finally contacted one development lead of .Net Winform team, and below is his comment:

    During databinding, the "new row" at the bottom gets added and removed several times - this adds some instances of the RowsAdded events. You could prevent this by setting this.dataGridView1.AllowUserToAddRows = false; in the designer.cs file
    ...
    So you may use DataSourceChanged event to enumerate all the rows and
    generate the combobox in each row during initial form_loading. In this period, you may suppress the using of RowAdded event through an internal flag. After setting AllowUserToAddRows property to true and last RowAdded event goes through, you may toggle that internal flag to use RowAdded event in the life time of the application. I hope this logic makes sense to you.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  19. #19
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    397
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 397
    Points : 130
    Points
    130
    Par défaut
    Je crois en effet que cela va m'aider!

    Je vais setter la propriété à false pendant que les données seront ajoutée, puis la remettre à true. Merci bien pour l'info

    Je vous tiens au courant si ç'est bon ou non

    L.

  20. #20
    Membre habitué
    Inscrit en
    Mai 2006
    Messages
    397
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 397
    Points : 130
    Points
    130
    Par défaut
    Bonne et mauvaise nouvelle!

    En setant this.dgvRates.AllowUserToAddRows = false; dans le fichier Designer.cs, je n'ai plus qu'un seul déclenchement de l'erreur de l'évènement RowDeleted.

    par contre si je mets la propriété à true lorsque j'ai ajouté mes données dans le datagridview, fait le sorting etc, la il m'affiche bien les 3 évènement rowdeleted.

    Est-ce que j'auras oublié de faire quelque chose par rapport à l'explication? Il me semble pas mais comme il me reste toujours un évènement...

    Par contre je ne comprend pas ce qu'il veut dire par le paragraphe suivant:

    So you may use DataSourceChanged event to enumerate all the rows and
    generate the combobox in each row during initial form_loading. In this period, you may suppress the using of RowAdded event through an internal flag. After setting AllowUserToAddRows property to true and last RowAdded event goes through, you may toggle that internal flag to use RowAdded event in the life time of the application. I hope this logic makes sense to you.
    Merci bien et bonne soirée

    L.

    [EDIT] Histoire que vous puissiez voir tout le code qui est appelé, voilà le code de le fichier winforms:

    Code C# : 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
    public partial class Rates : Form
        {
            public Rates()
            {
                InitializeComponent();
                MessageBox.Show("Initialize Component finished");
                LoadAreas();
            }
     
            private void LoadAreas()
            {
     
                dgvRates.DataSource = XMLQueriesRepository.LoadRatesXMLFileIntoDataSet().Tables[0];
                MessageBox.Show("Hiding id column");
                dgvRates.Columns["Id"].Visible = false;
                MessageBox.Show("Columns size");
                dgvRates.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
                MessageBox.Show("Sorting columns ");
                dgvRates.Sort(dgvRates.Columns["Grade"], ListSortDirection.Ascending);
                MessageBox.Show("LoadAreas finished");
                //dgvRates.AllowUserToAddRows = true;
            }
     
            private void btnBack_Click(object sender, EventArgs e)
            {
                this.Close();
            }
     
            private void dgvRates_RowValidated(object sender, DataGridViewCellEventArgs e)
            {
                MessageBox.Show("Row validated!");
            }
     
            private void dgvRates_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
            {
                MessageBox.Show("Row added!");
            }
     
            private void dgvRates_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
            {
                if (dgvRates.Created)
                {
                    MessageBox.Show("Row removed");//: " + dgvRates.Rows[e.RowIndex].ToString());
                }
     
                if (sender == null)
                {
                    MessageBox.Show("null");
                }
            }
     
            private void dgvRates_RowValidating(object sender, DataGridViewCellCancelEventArgs e)
            {
                MessageBox.Show("Row validating!");
            }
        }

    La fonction XMLQueriesRepository.LoadRatesXMLFileIntoDataSet() à le code suivant:

    Code C# : 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
    public static DataSet LoadRatesXMLFileIntoDataSet()
            {
                XDocument xmlFile = XDocument.Load(@"./../../Data/" + Program.__RatesXMLFile);
                XElement XMLParent = xmlFile.Root;
     
                DataSet ratesDataSet = new DataSet();
                ratesDataSet.Tables.Add("Rates");
                ratesDataSet.Tables["Rates"].Columns.Add("Id");
                ratesDataSet.Tables["Rates"].Columns.Add("Grade");
                ratesDataSet.Tables["Rates"].Columns.Add("Rate");
     
                var parents = from nodes in XMLParent.Elements() select nodes;
     
                foreach (var item in parents)
                {
                    ratesDataSet.Tables["Rates"].Rows.Add(
                        item.Attribute(Program.__ratesFields[0].ToString()).Value,
                        item.Attribute(Program.__ratesFields[1].ToString()).Value,
                        item.Value);
                }
     
                return ratesDataSet;
            }

    Voilà

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [AC-2003] Est-il possible de modifier en vba des données contenues dans un module ?
    Par elgordopresto dans le forum Access
    Réponses: 2
    Dernier message: 22/01/2015, 12h46
  2. [XL-2010] Supprimer des données filtrées dans un tableau
    Par virginie2 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 27/10/2014, 08h57
  3. [MySQL] Modifier et supprimer des données dans une base
    Par amandev dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 08/03/2012, 15h33
  4. Réponses: 2
    Dernier message: 25/08/2008, 10h41
  5. Réponses: 1
    Dernier message: 30/05/2007, 15h51

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