c# - WinForms C# 中优雅的日志窗口

标签 c# winforms logging

我正在寻找有关为 Windows 窗体应用程序实现日志窗口的有效方法的想法。过去我使用 TextBox 和 RichTextBox 实现了几个,但我仍然对这些功能不完全满意。

此日志旨在为用户提供各种事件的近期历史记录,主要用于数据收集应用程序,用户可能会好奇特定事务是如何完成的。在这种情况下,日志不需要是永久性的,也不需要保存到文件中。

首先,提出一些要求:

  • 高效快速;如果快速连续地将数百行写入日志,则需要消耗最少的资源和时间。
  • 能够提供最多 2000 行左右的可变回滚。任何更长的时间都是不必要的。
  • 突出显示和颜色是首选。不需要字体效果。
  • 在达到回滚限制时自动修剪行。
  • 添加新数据时自动滚动。
  • 奖励但不是必需的:在手动交互期间暂停自动滚动,例如用户正在浏览历史记录。

到目前为止,我一直在使用什么来编写和修剪日志:

我使用以下代码(我从其他线程调用):

// rtbLog is a RichTextBox
// _MaxLines is an int
public void AppendLog(string s, Color c, bool bNewLine)
{
    if (rtbLog.InvokeRequired)
    {
        object[] args = { s, c, bNewLine };
        rtbLog.Invoke(new AppendLogDel(AppendLog), args);
        return;
    }
    try
    {
        rtbLog.SelectionColor = c;
        rtbLog.AppendText(s);
        if (bNewLine) rtbLog.AppendText(Environment.NewLine);
        TrimLog();
        rtbLog.SelectionStart = rtbLog.TextLength;
        rtbLog.ScrollToCaret();
        rtbLog.Update();
    }
    catch (Exception exc)
    {
        // exception handling
    }
}

private void TrimLog()
{
    try
    {
        // Extra lines as buffer to save time
        if (rtbLog.Lines.Length < _MaxLines + 10)
        {
            return;
        }
        else
        {
            string[] sTemp = rtxtLog.Lines;
            string[] sNew= new string[_MaxLines];
            int iLineOffset = sTemp.Length - _MaxLines;
            for (int n = 0; n < _MaxLines; n++)
            {
                sNew[n] = sTemp[iLineOffset];
                iLineOffset++;
            }
            rtbLog.Lines = sNew;
        }
    }
    catch (Exception exc)
    {
        // exception handling
    }
}

这种方法的问题在于,每当调用 TrimLog 时,我都会丢失颜色格式。对于常规的 TextBox,这工作得很好(当然有一些修改)。

对此问题的解决方案的搜索从未真正令人满意。有些人建议通过 RichTextBox 中的字符数而不是行数来减少多余部分。我也见过使用 ListBoxes,但没有成功尝试过。

最佳答案

我建议您根本不要将控件用作日志。而是编写一个具有您想要的属性(不包括显示属性)的日志 collection 类。

然后编写将该集合转储到各种用户界面元素所需的少量代码。就个人而言,我会将 SendToEditControlSendToListBox 方法放入我的日志记录对象中。我可能会为这些方法添加过滤功能。

您可以仅在有意义的情况下更新 UI 日志,从而为您提供最佳性能,更重要的是,当日志快速变化时,您可以减少 UI 开销。

重要的是不要将您的日志记录绑定(bind)到一个 UI,那是错误的。有一天你可能想 headless 奔跑。

从长远来看,一个好的记录器 UI 可能是一个自定义控件。但在短期内,您只想断开您的日志记录与任何特定 UI 部分的连接。

关于c# - WinForms C# 中优雅的日志窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2196097/

相关文章:

c# - C#中的字节操作

c# - NHibernate 日志记录问题

c# - 如何在没有 try/catch block 的情况下记录单元测试中抛出的异常?

python - Paramiko Expect - 拖尾

c# - 有没有办法限制 Entity Framework 中列的值?

c# - C# 'is' 运算符是否会在 .NET 4 的 Release模式优化下受到影响?

c# - Entity Framework 将字符串转换为 Int

.net - WinForms:对象数据源使用最佳实践

vb.net - 将两个 MsgBoxStyles 与 VB.NET 合二为一

c# - 使用 Winform 更新 WPF 文本框用户控件中的文本