IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

[C#]ComboBox avec 30 000 items


Sujet :

Windows Forms

  1. #1
    Membre averti
    Inscrit en
    Janvier 2004
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 20
    Par défaut [C#]ComboBox avec 30 000 items
    Bonjour,

    J'ai une ComboBox avec 30000 items, l'affichage de cette ComboBox est extrêment lente. Pour limiter l'impact, j'utilise une structure de donnée que je remplit au chargement de l'application et que je garde en mémoire, les données n'étant pas modifiées au cours de la journée.

    Malgré le fait que ma structure de donnée soit en mémoire, je trouve le binding extrêmement long, j'utilise la méthode AddRange du ComboxBox.

    Est ce qu'il y a une méthode pour charger la ComboBox de manière optimale ?

    Pour contourner ce problème, j'ai essayé de garder une référence vers ma fenêtre qui contient cette ComboBox, au lieu de détruire la fenêtre, je fait un Hide(). Mais j'ai toujours un problème de performance avec la ComboBox lorsque j'affiche de nouveau la fenêtre (en fait, d'après ma recherche, la ComboBox est détruite lorsque l'on fait un Hide()).

    N'y a-t-il pas un moyen de garder une référence vers une fenêtre sans que les contrôles contenus dans celle-ci soit détruits ?

    Merci d'avance,

    Michael

    Cordialement,

    Michael Chevalier

  2. #2
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Par défaut
    1 - Suffit que ta fenetre ne soit pas détruire (donc, que la variable "fenetre" qui contient ta combo soit un membre de ta classe )

    2 - Tu peux utiliser le SuspendLayout et le ResumeLayout pour améliorer les données


    Après, petite remarque "gratuite", même si il y a surement une explication logique à la présence de 30000 Objets dans ta combo, celà me semble tellement aberrant que les bras m'en tombent .

    En effet, en tant qu'utilisateur, aller chercher une "référence" dans une combo de 30000 référence me semble vraiment incongru et peu pratique !!!

    Maintenant, ya surement comme je le dis une logique qui m'échappe liée au contexte d'utilisation.

    En tout cas, avec les pistes données, tu devrais pouvoir avancer rapidement !

  3. #3
    Rédacteur
    Avatar de Louis-Guillaume Morand
    Homme Profil pro
    Cloud Architect
    Inscrit en
    Mars 2003
    Messages
    10 839
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Cloud Architect
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 10 839
    Par défaut
    comme theMonz31, je pense qu'il y a clairement un problème dans l'utilisation d'une combobox. Si tu as 30 000 éléments, tu n'utilises surtout PAS une combobox.

    une simple textbox avec autocompletion ferait parfaitement l'affaire. ca prend dix lignes, et ca évite de faire des ruses d'ouzbek pour essayer d'amenuire la perte de performance suite à un mauvais choix ergonomique. Et au niveau performance, c'est ultra light l'autocompletion.

    pour la version simple, ca donne ceci: http://lgmorand.developpez.com/dotnet/autocompletion/
    mais le mieux c'est encore de faire une requête "à la ajax" pour éviter de retourner plus d'items que ce que l'on aura besoin.

  4. #4
    Membre averti
    Inscrit en
    Janvier 2004
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 20
    Par défaut
    Ma variable "Fenetre" est bien membre de ma classe Fenetre(pattern Singleton). J'ai créé une classe CustomComboBox pour surcharger la méthode WndProc, lorsque je fais un Hide() sur la fenêtre, j'intercepte un WM_DESTROY pour la ComboBox, et je me prends des message WM_ADDSTRING et d'autres messages lorsque j'affiche la fenêtre de nouveau.

    Du coup, le fait de garder l'instance de ma fenêtre perd de son intérêt du point de vue performance.
    Je n'ai plus trop de solutions pour améliorer les performances pour le moment.

  5. #5
    Rédacteur
    Avatar de Louis-Guillaume Morand
    Homme Profil pro
    Cloud Architect
    Inscrit en
    Mars 2003
    Messages
    10 839
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Cloud Architect
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 10 839
    Par défaut
    Je n'ai plus trop de solutions pour améliorer les performances pour le moment.
    on vient de te le dire.
    ton problème de performance, TU l'as créés en ajoutant une combobox là où il ne faut surtout pas l'utiliser. t'aurais le même problème avec beaucoup d'autres contrôles. Il n'y a que les listview en mode virtual qui peuvent gérer un grand nombre d'items.

    Utilise autre chose, ca serait performant et plus facile à utiliser pour l'utilisateur. comment veux-tu qu'un utilisateur choisisse parmi 30 000 items?²

  6. #6
    Membre averti
    Inscrit en
    Janvier 2004
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 20
    Par défaut
    Dans mon cas, la combobox est plutot fonctionnel une fois les données chargées. Les données de ma ComboBox viennent de ma couche Business, et j'utilise l'évènement OnKeyPress comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    // Custom behaviour for the custom combo box
    private void CustomComboBox_KeyPress(object sender, KeyPressEventArgs e)
            {
                switch ((Keys)e.KeyChar)
                {
                    case Keys.Down:
                        break;
                    case Keys.Up:
                        break;
                    case Keys.Enter:
                        // Close the drop down list
                        this.DroppedDown = false;
     
                        // Set the current selected index to the item selected
                        this.SelectedIndex = this.FindString(this.Text);
                        break;
                    default:
                        // Set the cursor at the end of the input string
                        if (string.IsNullOrEmpty(this.Text) == false)
                        {
                            this.Select(this.Text.Length, 0);
                        }
     
                        // Open the drop down list
                        this.DroppedDown = true;
                        break;
                }
            }
    Je trouve que la sélection est plutot simple, j'avais pas besoin de faire des requêtes. Je pense rester comme cela pour le moment.

    Merci

  7. #7
    Rédacteur
    Avatar de Louis-Guillaume Morand
    Homme Profil pro
    Cloud Architect
    Inscrit en
    Mars 2003
    Messages
    10 839
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Cloud Architect
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 10 839
    Par défaut
    désolé d'insister mais être obtu face à un problème qui n'en n'est pas n'est pas la solution

    Que ta liste soit donnée par ta couche business, c'est normal , mais le changement ne doit surement pas prendre plus d'une heure à tout casser pour faire un truc propre alors que ca fait des heures que tu cherches à bidouiller pour gagner en performance sur un mauvais choix technique.
    quel est l'intérêt de retourner 30 000 items si tu sais d'avance que ton utilisateur n'en n'utilisera qu'une seule partie?
    Vitesse? tu ne peux pas dire que c'est pour gagner du temps car c'est le contraire, tu perds en performance.
    Simplicité? non parce que tu dois bidouiller derrière en ajoutant une gestion de fenêtre alors que c'est juste une combo. depuis quand un composant impose un comportement à son parent?
    Si tu ne trouves pas de raison valable c'est que c'est pas le bon choix, tout simplement. Et MEME si tu trouvais une raison, le principe de la méthodologie LEAN est d'améliorer, toujours améliorer, donc tu trouverais forcément mieux que cette combobox retournant toutes les données.

    Tu as fais un choix en plaçant une dropdown. Au moment de ta décision, c'était la bonne solution (sûrement la meilleure même). Maintenant, aujourd'hui tu te rends compte que c'était une mauvaise idée, pourquoi ne veux-tu pas changer et corriger? Tous les logiciels ont parfois de lourdes refontes pour corriger une erreur passée, c'est normal et OBLIGATOIRE. ou alors, ton logiciel n'est pas un logiciel pro et dans ce cas, tu peux effectivement t'en moquer.


    solution
    dans le PIRE des cas, dans celui où tu es une grosse faignasse mais qui veut corriger son problème , tu te sers de ta méthode Key-press, et tu la fais évoluer pour filtrer la liste renvoyée par ta couche métier en fonction du texte saisi (un simple for-each). T'auras certes une boucle de plus, mais au moins ton UI ne ramera plus car tu ne bindes que les données nécessaires. ca prend 4 lignes en tout et pour tout

    Ensuite, tu te rendras compte que c'est dans ton intérêt d'avoir une couche business dont la liste des items est retournée en fonction d'un paramètre (texte) et qu'après ca ne te retournera que ce qui est nécessaire. Par expérience, je peux te le dire, c'est toujours plus performant, même si tu fais plusieurs accès bases, et tu ne donnes pas une appli lente aux utilisateurs.


    si après, tu veux t'obstiner dans la voix de la bidouille en ajoutant N lignes de code simplement pour éviter d'ajouter UN paramètre à ta couche métier et la procédure stockée qui est derrière, alors je n'insisterai plus. On est là pour aider et pour conseiller, et je respecterai ton choix (même s'il est erroné ).

Discussions similaires

  1. Charger une combobox avec Items.AddObject
    Par Delphi-ne dans le forum Composants VCL
    Réponses: 5
    Dernier message: 02/04/2015, 14h25
  2. Remplir un combobox avec les items d'un listbox
    Par kaygee dans le forum VB.NET
    Réponses: 4
    Dernier message: 23/05/2012, 09h13
  3. [AC-2007] Sélectionner un item d'une combobox avec une valeur?
    Par Vhalar dans le forum VBA Access
    Réponses: 1
    Dernier message: 08/09/2011, 22h07
  4. ComboBox avec item action
    Par bmeda72 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 17/08/2008, 19h01
  5. Réponses: 3
    Dernier message: 06/02/2008, 22h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo