代码之家  ›  专栏  ›  技术社区  ›  Serge van den Oever

Windows窗体在文本框中滚动日志输出的最佳方法

  •  30
  • Serge van den Oever  · 技术社区  · 17 年前

    在表单应用程序中,我显示了一个长时间运行的命令行应用程序的日志输出,该应用程序生成了大量输出。我在后台启动程序,捕获其输出,并使用AppendText将其显示在文本框中。例如,我更喜欢只显示最后1000行。从文本框中删除行是昂贵的,而且文本框并不是滚动日志显示的最佳方法。

    在Windows窗体中使用滚动日志窗口的最佳控件有什么想法?

    5 回复  |  直到 16 年前
        1
  •  16
  •   liggett78    17 年前

    我曾经让列表框做这种事情。如果行数达到(比如)1000,您只需删除第一行。如果日志行太长,可以将列表框加宽一点(取决于日志信息,以及是否可能在不进行水平滚动的情况下捕获第一个可见单词的含义),并使水平滚动条可见。

        2
  •  12
  •   Serge van den Oever    17 年前

        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();
             }
         }
    
        3
  •  7
  •   wipo wipo    17 年前

    我也有同样的需要,非常感谢你的帮助。这是一个稍微修改过的版本。

    创建列表框:

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

    在主线程(在代码的初始部分)中,将其用于存储对UI线程的引用:

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

    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
  •  3
  •   Smart Alec Smart Alec    17 年前

        5
  •  2
  •   Didier Ghys    14 年前

    非常简单的解决方案

    Textbox1.Appendtext(<yourtext>)
    

    推荐文章