在Forms应用程序中,我正在显示生成大量输出的长时间运行的命令行应用程序的日志输出。我在后台启动程序,捕获其输出,并使用AppendText将其显示在TextBox中。我更喜欢只显示例如最后1000行。从TextBox中删除行是很昂贵的,而TextBox实际上并不是滚动日志显示的最佳方法。
关于在Windows窗体中执行滚动日志窗口的最佳控件的任何想法?
答案 0 :(得分:15)
我曾经让列表框做过这种事情。如果行数达到1000,您只需删除第一行。如果日志行太长,您可以使列表框更宽一些(取决于日志信息以及是否可以从第一个可见的捕获含义)没有水平滚动的单词)并使水平滚动条可见。
答案 1 :(得分:11)
正是我需要的。我用下面的代码解决了这个问题,它保留了最后添加的项目:
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 :(得分:7)
有同样的需求并且非常感谢这个帮助。这是一个稍微修改过的版本。
创建一个列表框:
<ListBox x:Name="lbLog" Background="LightGray"></ListBox>
在主线程中(在代码的初始部分),将其存储为存储对UI线程的引用:
Thread m_UIThread;
....
m_UIThread = Thread.CurrentThread;
然后这是你的log方法,可以从任何线程调用:
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);
}
}
}
答案 3 :(得分:2)
我不久前需要这样做,而Listbox就是解决方案。没有人会注意到差异。
答案 4 :(得分:2)
非常简单的解决方案
Textbox1.Appendtext(<yourtext>)
用于滚动日志,如控制台