2009-07-22 6 views
1

J'essaie d'obtenir une zone de liste déroulante qui se comporte comme la méthode Delphi TMemo.Add(). En utilisant le code de test ci-dessous, il défile bien pendant un moment, puis s'arrête à environ 600 et ne parvient pas à rafraîchir jusqu'à ce que terminé.Comment garder l'affichage ListBox mis à jour pendant les appels .Add

J'ai vu des références à devoir exécuter le code ci-dessous sur un thread différent pour la mise à jour pour réussir. C'est le genre de chose que j'utilise régulièrement et j'espère une solution plus simple.

 for (int i = 0; i < 10000; i++) 
     { 
      listBox1.Items.Add(i); 
      listBox1.SetSelected(listBox1.Items.Count - 1, true); 
      listBox1.SelectedIndex = -1; 
      this.Refresh(); // overkill but just to make sure... 
     } 
+1

bienvenue à empiler débordement;) –

Répondre

2

Je ne recommanderais pas le faire que le coût de la performance de redessiner continue va vraiment tuer la vitesse, ce qui est ce que vous voyez à environ 600 - il est juste de trop pour qu'il puisse traiter.

Vous pouvez appeler le Application.Refresh pendant la boucle pour continuer à traiter les messages de la fenêtre, ce qui la fait réagir mais encore une fois au détriment des performances.

Une stratégie que j'ai vue récemment, qui n'est pas simple mais qui est efficace, est de simuler la liste. Ainsi, lors de l'ajout, vous masquez la liste et la remplacez par un panneau ou similaire que vous utilisez pour dessiner quelque chose qui ressemble à la liste. Lorsque vous avez terminé, vous retournez. De cette façon, vous obtenez très lisse, et potentiellement des effets plus attrayants visuellement. Plus de travail mais peut-être en vaut la peine.

0

Je n'ai pas utilisé application.refresh dans une boucle comme celle-ci (bien que cela puisse fonctionner parfaitement), vous pouvez essayer application.processMessages. J'ai utilisé cela et ça marche pour moi. -don

0

Vous pourriez vouloir penser différemment. Je suppose que vous voulez que la zone de liste soit redessinée chaque fois que vous ajoutez un élément pour montrer à l'utilisateur que vous progressez. Si tel est le cas, l'approche que je l'utilise dans des situations similaires est:

  1. Appel BeginUpdate sur le contrôle
  2. Faire le travail dans un autre thread
  3. Faire callbacks au fil de l'interface utilisateur d'ajouter un élément et mettre à jour une barre de progression. Lorsque votre travail est d'une durée indéterminée, exécutez Progressbar en mode Marquee à l'étape 1.
  4. Lorsque vous avez terminé, rappel au thread de l'interface utilisateur pour indiquer que le travail est terminé et donc un appel à EndUpdate doit être effectué.
0

Sur mon ordinateur, il fonctionne bien, jusqu'à ce que j'essaie d'interagir avec le formulaire, à quel point il arrêtera la mise à jour. Mais, ce n'est pas le point. La vraie question est, pourquoi voudriez-vous remplir une zone de liste avec 10000 articles et la mettre à jour pour chaque élément qui est affiché?

Une option raisonnable pourrait être de lot des objets (peut-être dans un thread séparé) et puis après un certain nombre d'éléments à afficher chaque maintenant et puis:

private void SomeMethod() 
{ 
    ThreadPool.QueueUserWorkItem((state) => 
     { 
      List<int> ints = new List<int>(); 
      for (int i = 0; i < 10000; i++) 
      { 
       ints.Add(i); 
       if (i % 25 == 0) // update the listbox on every 25th item 
       { 
        this.Invoke(
          new Action<IEnumerable<int>>(AddItemsToList), ints); 
        ints.Clear(); 
       } 
       if (ints.Count != 0) // make sure to add any "trailing" items 
       { 
        this.Invoke(
          new Action<IEnumerable<int>>(AddItemsToList), ints); 
       } 
      } 
     }); 
} 

private void AddItemsToList(IEnumerable<int> items) 
{ 
    listBox1.BeginUpdate(); 
    foreach (var item in items) 
    { 
     listBox1.Items.Add(item); 
    } 
    listBox1.EndUpdate(); 
    listBox1.SetSelected(listBox1.Items.Count - 1, true); 
    listBox1.SelectedIndex = -1; 
    listBox1.Update(); 
} 

Et maintenant, vous avez également une interface utilisateur assez réactif pendant le chargement de la liste.

Questions connexes