Enlever les doublons

Résolu/Fermé
sympatiqueCCM Messages postés 363 Date d'inscription jeudi 5 octobre 2006 Statut Membre Dernière intervention 26 juin 2023 - 6 sept. 2021 à 17:25
 Utilisateur anonyme - 20 sept. 2021 à 06:21
Bonjour,
Je cherche un truc pour enlever les doublons dans une ListBox.
La listbox est dejas trié dans la propriete Sort

Merci beaucoup de votre aide.



Configuration: Windows / Chrome 93.0.4577.63
A voir également:

18 réponses

Utilisateur anonyme
6 sept. 2021 à 19:00
Bonjour

Est elle bindée à une collection ?
0
sympatiqueCCM Messages postés 363 Date d'inscription jeudi 5 octobre 2006 Statut Membre Dernière intervention 26 juin 2023 11
6 sept. 2021 à 21:07
Non, c'est une ListBox qui est emplie a partir d'une colonne dans une List.

Merci...
0
yg_be Messages postés 23485 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 8 mars 2025 Ambassadeur 1 569
6 sept. 2021 à 21:16
bonjour,
généralement, si le tri est déjà fait, il suffit de parcourir et d'éliminer les éléments identiques au précédent.
0
Utilisateur anonyme
6 sept. 2021 à 22:30
Non, c'est une ListBox qui est emplie a partir d'une colonne dans une List.


donc non seulement le binding serait approprié, mais avec une requête Linq ce serait bindé sans doublon, et trié sans avoir besoin de Sort.

Peux tu poster le code qui rempli la listbox?

@yg_be, bonsoir, oui en général c'est vrai mais C# est pensé MVC voir MVVM, du coup il est préférable de traiter la source de données plutôt que le contrôle.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
sympatiqueCCM Messages postés 363 Date d'inscription jeudi 5 octobre 2006 Statut Membre Dernière intervention 26 juin 2023 11
7 sept. 2021 à 00:27
Merci Whismeril

foreach (Contact item in Contact.ListeContacts)
{
lstNom.Items.Add(item.Nom);
lstPrenom.Items.Add(item.Prenom);
lstNoTel.Items.Add(item.NumTel);
}


J'ai essayé pour les doublons

Int32 cnt = 0;
while (cnt < lstNom.Items.Count - 1)
{
if (lstNom.Items[cnt] == lstNom.Items[cnt + 1])
{
lstNom.Items.RemoveAt(cnt);
}
else
cnt++;
}

mais [cnt +1] n'est pas accepté, une exception est levé.
Je suis bloqué.

Merci encore Whismeril
0
Utilisateur anonyme
7 sept. 2021 à 07:55
Pour tes prochains post, merci d'utiliser la coloration syntaxique, voir ce petit tuto https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code

Laissons les doublons de coté un instant. C'est un cas d'école de "pourquoi le binding c'est vachement mieux"
Tu as une liste d'objets métier (ça c'est top, c'est la collection source) et tu veux afficher dans différents contrôles des information émanant de cette liste et donc contrôle par contrôle tu "t'emmerdes" à ajouter les infos les une après les autres.

Au final elle ne sont plus corrélées à la collection source. C'est p'tet ce que tu veux mais on va y revenir.

Avec le binding, déjà tu ne codes pas de boucles (y'en a forcément quelque part, mais c'est pas toi qui gère), mieux, pour tes contacts tu peux avoir une date de naissance et bien tu n'as pas besoin de convertir en string pour afficher dans une listbox, textobx etc....

En plus (et c'est là une force) quand tu sélectionnes un prénom, un nom, une date de naissance etc.... en fait c'est le contact que tu sélectionnes et donc pas besoin de rechercher dans la collection source pour trouver le contact à sélectionner.

Voici un tuto sur le sujet, ça tombe bien c'est avec des contacts https://codes-sources.commentcamarche.net/faq/1291-utilisation-du-binding-au-travers-de-l-objet-databindingsource et tu as le lien vers le projet d'exemple dedans.


Sauf que, peut-être si tu ne veux pas de doublons dans la liste de noms (et dans les autres) c'est pour appliquer des filtres.
Je n'ai pas traité ce cas dans le tuto, dans ce cas dit le et soit je mettrais le tuto à jour, soit je te dirais ici. Mais pas avant ce soir.


Ps

mais [cnt +1] n'est pas accepté, une exception est levé.
oui car cnt va jusque lstNom.Items.Count - 1 supposons 10 éléments, le dernier index c'est 9. Quand cnt va 9 l'élement cnt+1 (10) n'existe pas.


0
Utilisateur anonyme
8 sept. 2021 à 17:40
Bonsoir

Si tu ne m’en dit pas plus sur le besoin d’éliminer les doublons je ne saurais pas mite répondre
0
sympatiqueCCM Messages postés 363 Date d'inscription jeudi 5 octobre 2006 Statut Membre Dernière intervention 26 juin 2023 11
8 sept. 2021 à 21:05
Bonjours,

Je veux éliminer les doublons dans les ListBox parce que j'aliment ma liste avec les lListBox.
Si le nom ou prénom ne si trouve un TxtBox s'ouvre et i'nscrit le Mots. Cette liste va me servir a faire des requêtes sur les Contacts. Bon tu va me dire que c'est pas très utile ainsi mais je le fait ainsi parce que je test cela pour me faire une base de donné sur les diagnostique mécanique.

Merci beaucoup Whismeril.
0
Utilisateur anonyme
8 sept. 2021 à 22:50
J'ai pas compris, mais on va essayer d'avancer.
Je t'avoue que faire des tests sur des contacts pour finalement travailler sur des diagnostiques mécaniques, ça m'échappe un peu.

A partir des contacts, je me suis demandé si ta problématique de doublon est de ne pas avoir la même personne 2 fois ou si plusieurs personnes sont de la même famille n'avoir qu'une seule fois le nom de famille (la façon de faire sera différente ) mais en me parlant de mécanique, tu m'as perdu en conjonctures.... Je vais donc te poser d'autres questions pour essayer de mieux cerner ton besoin d'algo.

As tu lu le tuto sur le binding et essayer le projet de test?

Si oui en quoi ça te conviendrait et en quoi non?

En restant dans les contacts pour l'instant, ton besoin est il
  • de ne pas avoir 2 fois la même personne?
  • de ne pas avoir 2 fois le même prénom ou le même nom (ce que j'avais appelé faire des filtres, mais ça peut aussi servir à autre chose que filtrer)
  • les 2 besoins sont présents
  • autre

0
sympatiqueCCM Messages postés 363 Date d'inscription jeudi 5 octobre 2006 Statut Membre Dernière intervention 26 juin 2023 11
12 sept. 2021 à 22:59
Bonjours,

Je sais que ça semble bizzarre de prendre des listBox et supprimer
les doublons dans le cadre d'une base de données contenant des contacts.
Je veux voir comment ça marche dans ce petit projet dans le but
d'appliquer ce code dans un autre projet ou il sera très utile.

J'ai lu ton exemple Peronne et j'ai bindé les ListBox a ma
liste Contact, chacun avec son item de la liste.

Je veux bindé mon control bindingData avec la liste mais
ça ne fonctionne pas. J'ai un soulignement en rouge

            Contact ctt = new Contact();   //new Contact(); est souligné en //rouge
            Contact.ListeContacts.Add(ctt);
            contactBindingSource.DataSource = Contact.ListeContacts;


Voici ma Class Contact
      class Contact
    {
        public string Nom { get; set; }
        
        public string Prenom {  get; set; }

        public string NumTel {  get; set; }

        public static List<Contact> ListeContacts = new List<Contact>();   
        
        public Contact(string nom, string prenom, string numTel)
        {
            Nom = nom;
            Prenom = prenom;
            NumTel = numTel;
        }

        public static void SaveContacts(Contact contact)   // Methode surchargé pour enregister un seul contact
        {
            ListeContacts .Add (contact);
            string jsonString = 
            JsonSerializer.Serialize(Contact.ListeContacts);
            File.WriteAllText("bdd.json", jsonString);
        }

        public static void SaveContacts()   // Cette methode enregiste la totalité de contacts
        {
            string jsonString = 
            JsonSerializer.Serialize(Contact.ListeContacts);  
            File.WriteAllText("bdd.json", jsonString);  

        }

        public static void LoadFile()
        {
            if(File.Exists("bdd.json"))
            {
                string jsonString = File.ReadAllText("bdd.json");
                ListeContacts .Clear ();
                ListeContacts = JsonSerializer .Deserialize <List<Contact >> (jsonString) ;
            }
            
            
        }
            

    }


Mon besoin est de ne pas avoir 2 fois le même Nom dans la ListBox
(lstNom) et 2 fois le même Prénom dans la ListBox Prenom (lstPrenom)

Merci beaucoup de ton aide
0
Utilisateur anonyme
13 sept. 2021 à 07:32
C'est souligné en rouge OK, mais quel est le message d'erreur?
0
Pour les doublons tels que tu les souhaites, en détails

List<string> tousLesPrenoms = ListeContacts.Select(c => c.Prenom).ToList();//crée une liste qui contient tous les prénoms
List<string> prenomsSansDoublons = tousLesPrenoms.Distinct().ToList();//Crée une liste sans doublons, attention "Pierre" et "PIerre" sont 2 string différentes, ces 2 prénoms seront donc présent dans la liste
List<string> prenomsSansDoublonsTries = prenomsSansDoublons.OrderBy(c => c).ToList(); // tri dans l'ordre alphabétique
ListBoxPrenom.DataSource = prenomsSansDoublonsTries;


En condensé
ListBoxPrenom.DataSource = ListeContacts.Select(c => c.Prenom).Disctinct().OrderBy(c => c).ToList();
0
sympatiqueCCM Messages postés 363 Date d'inscription jeudi 5 octobre 2006 Statut Membre Dernière intervention 26 juin 2023 11
Modifié le 14 sept. 2021 à 22:56
Bonjours Whismeril,

J''ai réglé le problème de new Contacts();
J'ai codé un constructeur
public Contact()
        {
        }


Mais j'ai du abandonner ce bout de code parce qu'une exception non géré...

System.ArgumentException : 'Impossible de modifier la collection d'éléments
lorsque la propriété DataSource est définie"

j'ai inscrit le code que tu m'a donné et tout est sans erreur. Sauf que la ListBox est vide. Je suis a nouveau bloqué.
j'ai essayé
lstPrenom.Items.Add(item.Prenom);
et j'ai la même exception non gerée.

Je ne comprend pas très bien les expressions Lambda.
Est-ce que tu connais un document très pédagogique qui m'aiderais a comprendre la logique dans tous ça.

Merci encore.
0
J''ai réglé le problème de new Contacts();
J'ai codé un constructeur
ha ben oui, tu avais déjà un constructeur avec des paramètres, donc pour faire un new sans paramètres, il te fallait un constructeur vide.

System.ArgumentException : 'Impossible de modifier la collection d'éléments
lorsque la propriété DataSource est définie"
...
j'ai essayé lstPrenom.Items.Add(item.Prenom); et j'ai la même exception non gerée.
ça veut dire que ce contrôle est déjà bindé par ailleurs. Le binding a la priorité sur la gestion des items "à la main" et le binding par databindingsource a la priorité sur le binding par la propriété DataSource.


Pour les expressions lambda c'est simple. Je t'ai dit qu'avec Linq, tu ne code pas de boucle, mais qu'il y en a forcément quelque part. L'expression lambda c'est plus ou moins le code de cette boucle que tu ne codes pas. Ce qui est avant le => c'est la déclaration de la variable d'itération ce qui est après c'est ce qu'on en fait.

Exemple de Where, je veux sélectionner les contact qui ont plus de 20 ans
List<Contacts> toto = lesContacts.Where(c => c.Naissance.Year < 2002).ToList();

Si je devais faire une boucle ça donnerait
List<Contacts> toto  = new List<Contacts>();
foreach(Contact c in lesContacts)
{
     if(c.Naissance.Year < 2002)
               toto.Add(c);
}


Dans tout ça le lambda correspond à
Contact c 
et à
if(c.Naissance.Year < 2002)

Le reste, c'est le job de Where.


Dans un Select, le lambda définit les informations à extraire pour chaque item de la collection (l'item entier => pas de lambda, une propriété, le résultat d'une méthode, un calcul, un nouvel objet,.....-

Dans le OrderBy, le lambda définit la propriété à utiliser pour classer, dans mon exemple ces des strings, on classe sur l'objet "entier"
0
Utilisateur anonyme
15 sept. 2021 à 13:57
0
Utilisateur anonyme > Utilisateur anonyme
15 sept. 2021 à 14:00
Et pour linq
https://github.com/dotnet/try-samples#basics

Avant ils avaient fait un site avec chaque exemple expliqué, je n’ai pas testé le projet github
0
Utilisateur anonyme > Utilisateur anonyme
15 sept. 2021 à 19:20
ce site là a l'air pas mal https://linqsamples.com/
0
sympatiqueCCM Messages postés 363 Date d'inscription jeudi 5 octobre 2006 Statut Membre Dernière intervention 26 juin 2023 11
Modifié le 18 sept. 2021 à 23:04
Merci pour tes explications et les références.

j'ai utilisé ce code
lstrenom.DataSource = ListeContacts.Select(c => c.Prenom).Disctinct().OrderBy(c => c).ToList();


Ca fonctionnne super bien mais quand je veux ajouter un item a la ListBox j'ai un exception
"System.ArgumentException : 'Impossible de modifier la collection
d'éléments lorsque la propriété DataSource est définie.' "

Et dans les proprietes DataSource est (aucun).

Est-ce qu'il y a un moyen pour alimenter la ListBox sans utiliser DataSource?
J'essaie de bucher la dessus mais rien ne fonctionne.
0
Utilisateur anonyme
19 sept. 2021 à 08:25
Je n’ai pas été assez explicite à partir du moment où tu bindes la listbox, tu je peux plus agir directement sur elle.
Il faut agir sur la collection source.

Après avoir ajouté une personne dans la liste de contact, tu fait

lstrenom.DataSource = null; //pour reseter le binding précédent 
lstrenom.DataSource = ListeContacts.Select(c => c.Prenom).Disctinct().OrderBy(c => c).ToList();



0
sympatiqueCCM Messages postés 363 Date d'inscription jeudi 5 octobre 2006 Statut Membre Dernière intervention 26 juin 2023 11
19 sept. 2021 à 21:22
Merci beaucoup Whismeril,

Maintenant tout fonctionne a merveille.
Heureux d'avoir mis a profit ton expérience.

Tu est un excellent professeur.

Merci encore.
0
Utilisateur anonyme
19 sept. 2021 à 23:16
De rien, si j'ai pu t'aider, mais quand à être un excellent professeur, houla non, tu n'as vu qu'un aperçu de ce que peut faire le binding.
C'est très limité en winform. C'est en WPF que cela prend toute son ampleur.

Il y a par exemple des collections qui "préviennent" l'IHM qu'elles on changées, et donc dans le cas d'un ajout de contact, la liste sans doublon serait mise à jour sans supplémentaire.

0
sympatiqueCCM Messages postés 363 Date d'inscription jeudi 5 octobre 2006 Statut Membre Dernière intervention 26 juin 2023 11
20 sept. 2021 à 00:31
Bien sur je suis débutant, donc il serais préférable que je
j'apprennes le WPF !
0
Utilisateur anonyme
20 sept. 2021 à 06:21
Ça dépend. C'est beaucoup plus puissant que winform. Au final c'est aussi plus simple à personnaliser.
Mais il est impératif de penser "tout objet" et pas vaguement orienté objet afin de bien appliquer les pattern MVC ou MVVM. C'est uniquement en appliquant l'un ou l'autre que l'on exploite la puissance de WPF.
De plus il faut apprendre un second langage le XAML qui est celui avec lequel on écrit l'interface.
Cela nécessite donc plus d'effort, si tu apprends en même temps C#, XAML, MVC, MVVM.
Mais c'est faisable.

Si tu fais ce choix, je te conseil le livre "WPF par la pratique" de Thomas Lebrun. Bien meilleur prof que moi ;)
0