none
Revue de code : DataTable en List<Elem>

    Question

  • Bonjour tout le monde,

    Il y a peu j'ai vu proposer un code pour afficher le contenu d'un ComboBox en plusieurs colonnes :

    https://social.msdn.microsoft.com/Forums/sqlserver/fr-FR/1e4c0bf4-b686-4fa0-a6bd-75e50b7abf21/combobox-multi-colonnes-en-c?forum=netdevelopmentfr

    Au-delà de l'intérêt du sujet lui-même, ce projet peut aussi être le point de départ à quelques réflexions sur des façons de coder.

    J'ai proposé de cadrer différemment les colonnes, ça c'était encore dans le sujet, mais maintenant j'en sors.

    Pour faciliter la lecture du contenu de la ComboBox, on peut décider de lui passer des objets.

    	public class Elem
    	{
    		public int ID { get; set; }
    		public string Name { get; set; }
    		public Elem(int _id, string _name)
    		{
    			ID = _id;
    			Name = _name;
    		}
    	}
    

    Au demeurant j'ai mis ça en dessous de la classe du formulaire puisque je ne m'en sers que là. ça marche, mais je sais qu'il y a des contextes où c'est interdit.

    Voyons l'utilisation, d'abord l'initialisation de la collection. Les premières lignes n'entrent pas dans mon propos d'aujourd'hui, je les laisse juste pour situer à quel endroit je place le code.

    //comboBox1.DataSource = dtTest;
    comboBox1.DrawMode = DrawMode.OwnerDrawFixed;
    comboBox1.DisplayMember = "Name";
    comboBox1.ValueMember = "ID";
    
    
    List<Elem> Elems = new List<Elem>();
    foreach (DataRow r in dtTest.Rows)
    {
    	Elems.Add(new Elem(int.Parse(r[0].ToString()), r[1].ToString()));
    }
    
    comboBox1.DataSource = Elems;
    

    Ensuite dans le DrawItem, le DataRowView ne peut plus se référer au contenu du ComboBox, puisque celui-ci a changé de type :

    //ancien code : DataRowView drv = (DataRowView)this.comboBox1.Items[args.Index];

    DataView dv = new DataView(dtTest);

    DataRowView drv = (DataRowView)dv[args.Index];

    Un ComboBox basé sur une classe comme je l'ai proposé ne peut pas avoir une sélection nulle, donc par défaut on aura le premier élément de sélectionné. Ou alors il faudrait creuser au niveau de la classe pour autoriser les valeurs nulles.

    L'intérêt de ce mic-mac, comme je le disais, est de faciliter la lecture du contenu du ComboBox :

    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
    	MessageBox.Show(((Elem)comboBox1.SelectedItem).Name);
    }
    

    Alors je disais donc que j'avais une question, là-dessus. C'est au niveau de l'initialisation de la liste.

    Existe-t-il un moyen standard de convertir le contenu d'une DataTable en liste, ou était-ce bien ça qu'il fallait faire ?

    List<Elem> Elems = new List<Elem>();
    foreach (DataRow r in dtTest.Rows)
    {
    	Elems.Add(new Elem(int.Parse(r[0].ToString()), r[1].ToString()));
    }
    
    

    mardi 3 avril 2018 15:02

Réponses

  • Bonjour Gloops,

    Existe-t-il un moyen standard de convertir le contenu d'une DataTable en liste, ou était-ce bien ça qu'il fallait faire ?

    Un autre moyen serait la requête LINQ. Pourvu que les noms des colonnes de votre table de données soient Id et Nom, le code suivant pourrait vous aider :

         List<Elem> Elems = new List<Elem>();
         Elems = dtTest.AsEnumerable().Select(ligne => new Elem(ligne["Id"].ToString(), ligne["Nom"].ToString())
         ).ToList();

    Cordialement,
    Dimitar

    mercredi 4 avril 2018 13:52

Toutes les réponses

  • Bonjour Gloops,

    Existe-t-il un moyen standard de convertir le contenu d'une DataTable en liste, ou était-ce bien ça qu'il fallait faire ?

    Un autre moyen serait la requête LINQ. Pourvu que les noms des colonnes de votre table de données soient Id et Nom, le code suivant pourrait vous aider :

         List<Elem> Elems = new List<Elem>();
         Elems = dtTest.AsEnumerable().Select(ligne => new Elem(ligne["Id"].ToString(), ligne["Nom"].ToString())
         ).ToList();

    Cordialement,
    Dimitar

    mercredi 4 avril 2018 13:52
  • Ah, oui, c'était AsEnumerable() que j'avais oublié.

    C'est ça qui introduit la méthode ToList().

    Merci.

    Par la même occasion, si jamais il y a des critiques sur le code ...

    • Modifié Gloops mercredi 4 avril 2018 14:05
    mercredi 4 avril 2018 14:04
  • A propos, je me rappelle que l'espace de noms MVC (ou un espace de noms utilisé dans les applications MVC) propose une classe avec un entier ID et une chaîne de caractères, qui si je me rappelle bien s'appelle Name. On s'en sert d'ailleurs pour des listes déroulantes.

    ça aurait été pas mal à utiliser là, est-ce que c'est une bonne idée de déclarer en Winform un espace de noms usuellement utilisé en MVC ?

    mercredi 4 avril 2018 14:11