Récupérer le contenu d'un datagridview

Résolu
chambreur Messages postés 30 Date d'inscription mardi 19 août 2008 Statut Membre Dernière intervention 15 mai 2014 - Modifié par chambreur le 21/01/2014 à 14:45
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 - 23 janv. 2014 à 13:22
Bonjour,
Je possède un datagridview généré à partir d'une datatable créée a partir de 3 lists.
Je souhaites désormais récupérer le contenu des lignes modifiées par l'utilisateur par l'intermédiaire du datagridview, mettre les nouvelles lignes dans une autre liste et les comparer.
on sait que le code suivant fonctionne et permet de récupérer la valeur d'une seul cellule:
string case1 = datagridview1[1, 0].Value.ToString();

Je souhaite donc récupérer toute une ligne et l'insérer dans une liste comme ceci
List<string> NelleListe = new List<string>();
NelleListe = datagridview1.Rows[2].Cells.ToList(); 

Ceci bien évidement ne fonctionne pas. Peut être qu'il n'y a pas de solution simple et que je dois ajouter les cellules une à une dans une liste mais je pense qu'il doit y avoir une solution pour faire ça en 1 coup (très rapidement)

tout comme
List<string> times = temps.OfType<string>().ToList();
dt.Rows.Add(times.ToArray());  // sert à  afficher les lignes du tableau

M'a permis de créer très facilement ma datatable

Une idée?

7 réponses

Whismeril Messages postés 19038 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 656
22 janv. 2014 à 20:15
Bonsoir, c'est pour ça que je t'avais orienté vers le binding lors de ta présente question.

soit le fichier xml suivant
<?xml version="1.0" encoding="utf-8" ?> 
- <ListeDeContacts>
- <Contact>
  <Nom>Di</Nom> 
  <Prenom>Alain</Prenom> 
  <Naissance>01/02/1900</Naissance> 
  </Contact>
- <Contact>
  <Nom>Sor</Nom> 
  <Prenom>Jean</Prenom> 
  <Naissance>01/01/1900</Naissance> 
  </Contact>
- <Contact>
  <Nom>Zétofrai</Nom> 
  <Prenom>Mélanie</Prenom> 
  <Naissance>01/03/1900</Naissance> 
  </Contact>
  </ListeDeContacts>



tu veux lire et afficher ce fichier dans un datagridview et que les modifications de l'utilisateur soient enregistrées

I j'écris une classe qui décrit ma structure de données
using System;

namespace test
{
    public class Contact
    {
        public string Nom { get; set; }

        public string Prenom { get; set; }

        public DateTime Naissance { get; set; }
    }
}

c'est réduit au strict minimum, 1 using 3 propriétés

II j'écris une classe statif qui lit et écrit le xml
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace test
{
    public static class AccesXML
    {

        /// <summary>
        /// Méthode pour lire le xml
        /// </summary>
        /// <param name="fichier">chemin du fichier</param>
        /// <returns>une liste de contacts</returns>
        public static List<Contact> LireContacts(string fichier)
        {
            XDocument xDoc = XDocument.Load(fichier);

            List<Contact> contacts;// on peux éviter cette ligne mais je décompose pour l'exemple

            contacts = (from c in xDoc.Descendants("Contact")//dans xDoc, on passe en revue chaque occurence de "Contact"
                        select new Contact//crée une nouvelle instance de ma classe Contact
                        {
                            Nom = c.Element("Nom").Value,
                            Prenom = c.Element("Prenom").Value,
                            Naissance = Convert.ToDateTime(c.Element("Naissance").Value)
                        }
                        ).ToList<Contact>();//cast le resultat de la requette du type Iennumerable<Contact> en List<Contact>

            return contacts;
        }

        /// <summary>
        /// Méthode qui ecrit le xml
        /// </summary>
        /// <param name="Contacts">La liste de contacts</param>
        /// <param name="fichier">chemin du fichier</param>
        public static void EcritContacts(List<Contact> Contacts, string fichier)
        {
            XDocument xDoc = new XDocument(
                                new XElement("ListeDeContacts", //une balise 
                                        from c in Contacts
                                        orderby c.Prenom ascending //triés par prénom pour le principe 
                                        select new XElement("Contact",
                                        new XElement("Nom", c.Nom),//on écrit l'élement Nom
                                        new XElement("Prenom", c.Prenom),//on écrit l'élement Prénom
                                        new XElement("Naissance", c.Naissance.ToShortDateString())// on écrit l'élément date de naissance 
                                )));
            xDoc.Save(fichier);
        }
    }
}

L'intérêt de faire une classe static à voir dans les commentaires du formulaire


III Je prends, un formulaire tout neuf, j'y mets un datagridview et le binde sur ma classe Contact par cette méthode
Dans le load j'appelle la méthode qui remplie le tableau et dans l'événement contactBindingSource_CurrentItemChanged la méthode qui sauve le xml.

using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;

namespace test
{
    public partial class Form4 : Form
    {

        List<Contact> contacts;

        public Form4()
        {
            InitializeComponent();
        }

        private void Form4_Load(object sender, EventArgs e)
        {
            AfficheContact();
        }

        /// <summary>
        /// affiche le fichier xml dans le datagridview
        /// </summary>
        private void AfficheContact()
        {
            if (File.Exists("Contacts.xml"))
                contacts = AccesXML.LireContacts("Contacts.xml");//charge le fichier s'il existe
                //on voit ici l'interet que AccesSML soit une classe statique:
                //il n'y a pas besoin d'instancier une variable pour utiliser la méthode
            else
                contacts = new List<Contact>();//sinon initialise une liste vide

            contactBindingSource.DataSource = contacts;//binde la liste de contacts
        }

        /// <summary>
        /// enregistre le xml dès qu'une entrée est validée dans le datagridview
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void contactBindingSource_CurrentItemChanged(object sender, EventArgs e)
        {
            if (contacts.Count > 0)
                AccesXML.EcritContacts(contacts, "Contacts.xml");
                //on voit ici l'interet que AccesSML soit une classe statique:
                //il n'y a pas besoin d'instancier une variable pour utiliser la méthode
            else
                File.Delete("Contacts.xml");
        }
    }
}


et voilà (clique sur l'image pour agrandir)



Dans cet exemple au moindre changement validé dans le datagridview (on quitte une cellule ou on tape sur entrée), le xml est modifié.
Ce qui implique qu'en cours de création d'un nouveau contact le xml présente un enregistrement moitié rempli, mais j'ai codé vite fait.
On peut aussi ajouter un bouton "Enregistrer" et ne pas se servir de l'événement.

PS pour les jeux de mots j'ai changé l'ordre des colonnes ;-)
4