Best approach to Windows Forms rolling log output

2019-01-21 19:26发布

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?

5条回答
等我变得足够好
2楼-- · 2019-01-21 19:55

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.

查看更多
走好不送
3楼-- · 2019-01-21 20:01

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);
        }
    }
}
查看更多
女痞
4楼-- · 2019-01-21 20:02

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

查看更多
小情绪 Triste *
5楼-- · 2019-01-21 20:05

very simple solution

Textbox1.Appendtext(<yourtext>)

for rolling log like console

查看更多
手持菜刀,她持情操
6楼-- · 2019-01-21 20:08

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();
         }
     }
查看更多
登录 后发表回答