Afficher les textes dans un ComboBox avec items = objets

Résolu
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 - Modifié le 7 janv. 2018 à 18:53
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 - 7 janv. 2018 à 20:34
Bonjour,
Désolé pour le style télégraphique du sujet, mais le nombre de caractères est limité...

Je me trouve devant un problème tout bête avec une ComboBox.
J'ai besoin d'avoir deux infos dans chaque item de la ComboBox : une pour l'affichage, l'autre pour une donnée utilisable ailleurs.
En VB6, on avait la propriété ItemData, qui avait la fâcheuse particularité d'être uniquement numérique, mais on arrivait à s'en sortir.
En C#, les items du contrôle peuvent être des objets, ce qui est beaucoup plus intéressant. Mais voila, je ne sais pas comment définir ce qu"il faut afficher dans le texte des items.

Un exemple précis: J'ai besoin de deux informations pour chaque item : un texte à l'affichage, et un chemin pour accéder aux données représentées par ce texte.
J'ai donc créé pour chaque item une KeyValuePair, dont la clé est une de ces deux infos, et la valeur l'autre. J'ai ajouté cet item à la ComboBox sans problème. Mais...
A l'affichage, le contrôle présente l'item comme avec ToString (logique), soit la présentation "[clé, valeur]" (voir image)

Ce n'est pas du tout ce que je souhaite. Je voudrais pouvoir sélectionner une des deux parties et une seule (la partie valeur de préférence, la clé devant être unique).
Pour la récupération de l'item et son traitement, je pense que je saurai faire.

Mais comment n'afficher que la valeur de la KeyValuePair dans la ComboBox, sans faire une usine à gaz ?
Car bien sûr, je pourrais faire à côté un dictionnaire, ne mettre que les textes dans la ComboBox, et faire une recherche de l'item sélectionné dans le dictionnaire, ou mieux lier la propriété DataSource au dictionnaire... Mais j'espère qu'il y a beaucoup plus simple. Surtout qu'il peut y avoir plusieurs fois le même texte, correspondant à des clés différentes.

Merci pour une idée (surtout sans créer un objet supplémentaire).

6 réponses

NHenry Messages postés 15113 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 22 avril 2024 159
7 janv. 2018 à 18:52
Tu peux compléter la classe de tes objets avec ton ToString pour retourner ce que tu souhaites.
Sinon, tu te refais ta propre classe qui prends en constructeur 2 paramètres : l'objet et la chaine associée et affiche dans son ToString la chaine souhaitée.
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
7 janv. 2018 à 19:17
Bonsoir, en complément d'un ToString() personnalisé (qui est une bonne solution), tu peux utiliser le binding
http://codes-sources.commentcamarche.net/faq/1291-utilisation-du-binding-au-travers-de-l-objet-databindingsource
0
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 2
7 janv. 2018 à 19:18
Les items ne sont pas une classe mais des KeyValuePair, objet intrinsèque au Framework. Je ne peux pas maîtriser le ToString() de cet objet sans faire du code supplémentaire. Je ne suis même pas sur que cet objet soit dérivable.

J'ai dit que je ne souhaitais pas créer un objet supplémentaire.
La solution "propre", je la connais : gérer un dictionary, et lier ce dictionnaire au DataSource de la combobox, l'affichage se faisant avec DisplayMember.

Mais justement, je souhaiterais ne pas avoir à gérer cela, le remplissage de la combobox se faisant à la volée, et la gestion d'un dictionnaire avec ses mises à jour étant délicate. De plus, je ne suis pas sûr qu'une modification du dictionnaire (ou d'une classe équivalente) soit répercutée immédiatement dans la combobox.
0
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 2
7 janv. 2018 à 19:38
Merci Whismeril pour le lien, mais cela concerne la liaison avec une base de données, ce qui n'est pas le cas actuel (d'ailleurs depuis moult années, Microsoft ne pense QUE base de données, ce qui m'avait mis en fureur lors d'un séminaire Microsoft où j'avais besoin de liaisons techniques essentiellement basées sur de la communication série et Ethernet).

J'ai tenté de lier un Dictionary<string, String> à la propriété DataSource de ma ComboBox, mais j'ai obtenu une exception "DataBinding complexe accepte IList ou IListSource comme source de données" à la ligne MaCombo.DataSource = MonDico;

Bref, la solution du ToString personnalisé d'un KeyValuePair (ou autre couple de données) me tente assez, mais je ne sais pas le faire....
Un petit tuto ?
0

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

Posez votre question
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
7 janv. 2018 à 19:52
mais cela concerne la liaison avec une base de données,
absolument pas.
0
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 2
7 janv. 2018 à 20:34
Bon, finalement, j'ai trouvé la solution tout seul, mais pas sans faire de code.
J'ai créé la petite classe suivante:

public class ListItem
{
    public object Tag { get; set; }
    public string Text { get; set; }
    public ListItem() {}
    public ListItem(object obj, string display) { Tag = obj; Text = display; }
    public override string ToString() { return Text; }
}

et ça fait parfaitement l'affaire. pour remplir ma ComboBox, je fais :
MaCombo.Items.add(new ListItem(quelquechose, letitre));

et la combo m'affiche bien le texte letitre.
Et je pense pouvoir récupérer le quelquechose en faisant:
montruc =((ListItem)MaCombo.SelectedItem).Tag;

mais je n'ai pas encore essayé.

Aurais-je réinventé la propriété Tag que l'on trouve dans pratiquement tous les autres contrôles à liste? (TreeView, ListView, etc.)
0
Rejoignez-nous