2008-12-20 7 views
27

Dans une application Forms, j'affiche une sortie de journal à partir d'une application de ligne de commande longue qui a généré beaucoup de résultats. Je démarre le programme en arrière-plan et capture sa sortie et l'affiche actuellement dans un TextBox en utilisant AppendText. Je préfère ne montrer que par exemple les 1000 dernières lignes. Supprimer des lignes d'un TextBox coûte cher, et un TextBox n'a pas vraiment l'impression d'être la meilleure approche pour afficher un journal.Meilleure approche de la sortie du journal de roulement de Windows Forms dans TextBox

Des idées sur le meilleur contrôle pour faire une fenêtre de journal roulant dans Windows Forms?

Répondre

12

J'avais l'habitude d'avoir des boîtes de liste faire ce genre de chose. Vous supprimez simplement la première ligne si le nombre de lignes atteint, par exemple, 1000. Si la ligne de journal est trop longue, vous pouvez agrandir la liste (dépend des informations du journal et de la possibilité de capturer le sens du premier mots sans défilement horizontal) et rendre la barre de défilement horizontale visible.

+1

je fait la même chose aussi. En fonction de votre ordre de tri (dernière insertion en haut ou en bas), vous pouvez également mettre en surbrillance la dernière ligne – faulty

2

J'avais besoin de faire cela il y a un certain temps et la Listbox était la solution. Personne ne remarquera même la différence.

11

exactement ce dont j'avais besoin. Je l'ai résolu avec le code suivant qui conserve le dernier élément ajouté visible:

delegate void UpdateCCNetWindowDelegate(String msg); 

    private void Message2CCNetOutput(String message) 
    { 
     // Check whether the caller must call an invoke method when making method calls to listBoxCCNetOutput because the caller is 
     // on a different thread than the one the listBoxCCNetOutput control was created on. 
     if (listBoxCCNetOutput.InvokeRequired) 
     { 
      UpdateCCNetWindowDelegate update = new UpdateCCNetWindowDelegate(Message2CCNetOutput); 
      listBoxCCNetOutput.Invoke(update, message); 
     } 
     else 
     { 
      listBoxCCNetOutput.Items.Add(message); 
      if (listBoxCCNetOutput.Items.Count > Program.MaxCCNetOutputLines) 
      { 
       listBoxCCNetOutput.Items.RemoveAt(0); // remove first line 
      } 
      // Make sure the last item is made visible 
      listBoxCCNetOutput.SelectedIndex = listBoxCCNetOutput.Items.Count - 1; 
      listBoxCCNetOutput.ClearSelected(); 
     } 
    } 
+2

En règle générale, pour les journaux de roulement, j'aime conserver les éléments les plus récents en haut. Un utilisateur peut être confus s'il lit une ligne apparemment statique en haut de la liste qui disparaît soudainement. –

7

Avait le même besoin et beaucoup apprécié cette aide. Ceci est une version légèrement modifiée.

Créer une zone de liste:

<ListBox x:Name="lbLog" Background="LightGray"></ListBox> 

Dans le thread principal (dans la partie intial du code), mettre ce pour stocker une référence au fil de l'interface utilisateur:

Thread m_UIThread; 
.... 
m_UIThread = Thread.CurrentThread; 

Alors ceci est votre méthode de journal, appelable de tout fil:

public void AddToLog(String message)  
{ 
    if (Thread.CurrentThread != m_UIThread) 
    { 
     // Need for invoke if called from a different thread 
     this.Dispatcher.BeginInvoke(
      DispatcherPriority.Normal, (ThreadStart)delegate() 
      { 
       AddToLog(message); 
      }); 
    } 
    else 
    { 
     // add this line at the top of the log 
     lbLog.Items.Insert(0, message); 

     // keep only a few lines in the log 
     while (lbLog.Items.Count > LOG_MAX_LINES) 
     { 
      lbLog.Items.RemoveAt(lbLog.Items.Count-1); 
     } 
    } 
} 
+0

Cela a fonctionné très bien pour moi. Merci! –

+1

Le répartiteur suit le fil, il a été créé en vous n'avez pas besoin m_UIThread ... donc au lieu de tests si (Thread.Current! = M_UIThread) vous pouvez simplement utiliser if (! Dispatcher.CheckAccess() http://msdn.microsoft.com/fr-fr/library/system.windows.threading.dispatcher.checkaccess.aspx –

3

solution très simple

Textbox1.Appendtext(<yourtext>) 

pour journal roulant comme console

+1

Downvoted. Ne supprime pas le vieux texte avec cette solution. –

Questions connexes