views:

2750

answers:

8

In a Forms application I'm displaying log output from a long running command-line application that generated a lot of output. I start the program in the background, and capture its output and currently display it in a TextBox using AppendText. I prefer to only display for example the last 1000 lines. Removing lines from a TextBox is expensive, and a TextBox does not really feels like the best approach for rolling log display.

Any ideas on the best Control to do a rolling log window in Windows Forms?

+3  A: 

I used to have listboxes do this kind of thing. You just remove the first line if the line count reaches, say, 1000. If the log line is too long, you could make the listbox a bit wider (depends on the log information and whether it's possible to catch the meaning from the first visible words without horizontal scrolling) and make the horizonal scrollbar visible.

liggett78
I did the same too. Depending on your sort order (latest insert top or bottom), you could highlight the latest line too
faulty
+1  A: 

I needed to do this a while ago and the Listbox was the solution. No one will even notice the difference.

+1  A: 

Hi guys, exactly what I needed. I solved it with the following code which keeps the last added item 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();
         }
     }
Serge van den Oever
As a general rule, for rolling logs, I like to keep the most recent items at the top. A user might be confused if they're reading an apparently static line at the top of the listbox that suddenly just disappears.
Greg D
A: 

Could you please post the whole code ?

A: 

Hey, thanks for this, works great.

A: 

Thanks, the code above works well. I'm sure there's a framework somewhere that does this, but for a quick and dirty line of business utility its more than fine.

Cephas
A: 

Had the same need and appreciated a lot this help. This is a slightly modified version.

Create a listbox:

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

In the main thread (in the intial part of the code),put this to store a reference to the UI thread:

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

Then this is your log method, callable from any thread:

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);
        }
    }
}
A: 

I'm about to try something like this. However I think I'm going to try to out put to a console window. I'm not sure what the limit is. I'm debugging my app now and I'm doing to file moving on the file server. The out window is on line 28763 right now. It adds about 5 lines a second. I'd like to see that console type output window when my program is deployed.

Jesse Seger