none
Linq - combobox : Problèmes avec le orderby RRS feed

  • Question

  • Bonjour ... alors voilà j'ai deux tables : une localite et une cp (code postal). Sachant qu'un code postal peut avoir plusieurs localité. Je voudrais afficher la liste de mes villes dans une combobox et le code postal lui correspondant dans un label juste à coté. Pour le moment j'y arrive mais uniquement lorsque je laisse les données dans l'ordre de ma table. Or je voudrais qu'il s'affiche dans ma combobox par ordre alphabétique et là cela pose problème car dès lors l'index change.

    La fonction suivante je la lance dans le load de ma WindForm

     private void VilleCombo()
            {
                db = new mydbEntities();
                var listVilles = (from localite in db.localite 
                                  join cp in db.localite
                                  on localite.idCP equals cp.idCP 
                                  select new {localite.nom,cp}
                                  );
                comboVille.DataSource = listVilles;
                comboVille.DisplayMember = "nom";
                comboVille.ValueMember = "idCP";
              
            }

     Ensuite à chaque changement et sélection d'une ville dans ma combo : 

    private void comboVille_SelectedIndexChanged(object sender, EventArgs e)
            {                     
                int combo = comboVille.SelectedIndex;
                combo = combo + 1;
                int listCP = (from cp in db.cp
                              where cp.idCP == combo                       
                              select cp.num).FirstOrDefault();
                lb_cp.Text = Convert.ToString(listCP);
            }

    Merci d'avance.

    Gael Matendo

    vendredi 15 juin 2012 10:49

Réponses

  • Au temps pour moi. C'était juste pour montrer un exemple qui marche, l'utilisation de EF (dont le principe est justement d'exposer des données comme des objets .NET habituels) ne faisant pas de différence particulière. Cela donne par exemple :

          private anonEntities c = new anonEntities();
            public class Data
            {
                public string Nom { get; set; }
                public int pk {set;get;}
                public string Descriptif { get; set; }
            }
            public Form1()
            {
                InitializeComponent();
                comboBox1.DataSource = from o in c.Opération orderby o.Nom select new Data { pk = o.Opération_pk, Nom = o.Nom, Descriptif = o.Descriptif };
                comboBox1.DisplayMember = "Nom";
            }
    
            private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
                Data d = (Data)comboBox1.SelectedValue;
                lblDescriptif.Text = d.Descriptif;
            }

    La seule différence est donc que la liste a été tirée d'une base au lieu d'être initialisée avec des données d'exemple et en utilisant un objet chargé de fournir les données, il serait même impossible en voyant le code de savoir d'où viennent les données et le même code pourrait aussi bien marcher avec des données d'exemple initialisées "en dur" qu'avec des données en provenance d'une base...

    Dans votre cas vous pouvez soit inclure num dans les données de la première requête ce qui rend inutile d'accèder à la base dans le SelectedIndexChanged ou alors si vous ne gardez que la pk, continuer à faire une autre requête pour aller chercher les données.

    Je me concentrais jusqu'ici plutôt sur le fait que si on a besoin de la pk il est plus simple de récupérer directement la pk (donc via SelectedValue si on fait un ValueMember="pk") et que l'on peut même récupérer carrément l'objet sélectionnée (si on ne précise pas ValueMember) ce qui permet d'accèder à n'importe quelle propriété exposée par cet objet.


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".





    vendredi 15 juin 2012 11:59
    Modérateur

Toutes les réponses

  • Bonjour,

    Le mieux est d'être toujours le plus direct possible. Déduire le idCP de la position dans la liste dépend du tri et ne fonctionnera plus dès que l'on aura un trou car de fait il n'y a aucun lien direct entre les deux. Donc autant récupérer directement l'id. Par exemple :

           public class Data
            {
                public string Nom { get; set; }
                public int Id {set;get;}
            }
            public Form1()
            {
                InitializeComponent();
                comboBox1.DataSource = new System.Collections.Generic.List<Data>{
                    new Data() { Nom = "A", Id = 10 },
                    new Data() { Nom = "C", Id = 2 },
                    new Data() { Nom = "B", Id = 3 }
                }.OrderBy(f => f.Nom).ToList();
                comboBox1.DisplayMember = "Nom";
            }
    
            private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
                Data d = (Data)comboBox1.SelectedValue;
                MessageBox.Show(d.Id + " - " +d.Nom);
            }
    La source de la combox est une liste d'objets, on peut donc récupérer l'objet sélectionné et accéder à n'importe laquelle de ses propriétés...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".


    vendredi 15 juin 2012 11:14
    Modérateur
  • Okay ... Sauf que l'idCP je dois absolument aller le rechercher dans une base de données. C'est pour ça que je fais cette connection à la mydbentities.

    La méthode que vous me donnez ne fait aucunes connection à une base de données ... si je ne me trompes pas ?

    vendredi 15 juin 2012 11:21
  • Au temps pour moi. C'était juste pour montrer un exemple qui marche, l'utilisation de EF (dont le principe est justement d'exposer des données comme des objets .NET habituels) ne faisant pas de différence particulière. Cela donne par exemple :

          private anonEntities c = new anonEntities();
            public class Data
            {
                public string Nom { get; set; }
                public int pk {set;get;}
                public string Descriptif { get; set; }
            }
            public Form1()
            {
                InitializeComponent();
                comboBox1.DataSource = from o in c.Opération orderby o.Nom select new Data { pk = o.Opération_pk, Nom = o.Nom, Descriptif = o.Descriptif };
                comboBox1.DisplayMember = "Nom";
            }
    
            private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
                Data d = (Data)comboBox1.SelectedValue;
                lblDescriptif.Text = d.Descriptif;
            }

    La seule différence est donc que la liste a été tirée d'une base au lieu d'être initialisée avec des données d'exemple et en utilisant un objet chargé de fournir les données, il serait même impossible en voyant le code de savoir d'où viennent les données et le même code pourrait aussi bien marcher avec des données d'exemple initialisées "en dur" qu'avec des données en provenance d'une base...

    Dans votre cas vous pouvez soit inclure num dans les données de la première requête ce qui rend inutile d'accèder à la base dans le SelectedIndexChanged ou alors si vous ne gardez que la pk, continuer à faire une autre requête pour aller chercher les données.

    Je me concentrais jusqu'ici plutôt sur le fait que si on a besoin de la pk il est plus simple de récupérer directement la pk (donc via SelectedValue si on fait un ValueMember="pk") et que l'on peut même récupérer carrément l'objet sélectionnée (si on ne précise pas ValueMember) ce qui permet d'accèder à n'importe quelle propriété exposée par cet objet.


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".





    vendredi 15 juin 2012 11:59
    Modérateur