WinForms C# 中优雅的日志窗口

2024-02-27

我正在寻找一种有效的方法来实现 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 时,我都会丢失颜色格式。对于常规文本框,这工作得很好(当然需要进行一些修改)。

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


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

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

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

重要的是不要将日志记录与 UI 部分联系起来,这是一个错误。有一天你可能想无头跑。

从长远来看,一个好的记录器 UI 可能是一个自定义控件。但从短期来看,您只想断开日志记录与任何specific用户界面的一部分。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WinForms C# 中优雅的日志窗口 的相关文章

  • 如何区分用户点击链接和页面自动重定向?

    拥有 C WebBrowser control http msdn microsoft com en us library system windows forms webbrowser aspx在我的 WinForms 应用程序中 并意识
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 为什么 Google 测试会出现段错误?

    我是 Google Test 的新手 正在尝试提供的示例 我的问题是 当我引入失败并设置GTEST BREAK ON FAILURE 1 或使用命令行选项 GTest 将出现段错误 我正在考虑这个例子 https code google c
  • 在 C 中初始化变量

    我知道有时如果你不初始化int 如果打印整数 您将得到一个随机数 但将所有内容初始化为零似乎有点愚蠢 我问这个问题是因为我正在评论我的 C 项目 而且我对缩进非常直接 并且它可以完全编译 90 90 谢谢 Stackoverflow 但我想
  • 从 Linux 内核模块中调用用户空间函数

    我正在编写一个简单的 Linux 字符设备驱动程序 以通过 I O 端口将数据输出到硬件 我有一个执行浮点运算的函数来计算硬件的正确输出 不幸的是 这意味着我需要将此函数保留在用户空间中 因为 Linux 内核不能很好地处理浮点运算 这是设
  • 我可以使用 moq Mock 来模拟类而不是接口吗?

    正在经历https github com Moq moq4 wiki Quickstart https github com Moq moq4 wiki Quickstart 我看到它 Mock 一个接口 我的遗留代码中有一个没有接口的类
  • 如何检测表单的任何控件的变化?

    如何检测 C 中表单的任何控件的更改 由于我在一个表单上有许多控件 并且如果表单中的任何控件值发生更改 我需要禁用按钮 我正在寻找一些内置函数 事件处理程序 属性 并且不想为此创建自定义函数 不 我不知道任何时候都会触发任何事件any控制表
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • Azure 辅助角色“请求输入之一超出范围”的内部异常。

    我在辅助角色中调用 CloudTableClient CreateTableIfNotExist 方法 但收到一个异常 其中包含 请求输入之一超出范围 的内部异常 我做了一些研究 发现这是由于将表命名为非法表名引起的 但是 我尝试为我的表命
  • 如何禁用 fread() 中的缓冲?

    我正在使用 fread 和 fwrite 读取和写入套接字 我相信这些函数用于缓冲输入和输出 有什么方法可以在仍然使用这些功能的同时禁用缓冲吗 Edit 我正在构建一个远程桌面应用程序 远程客户端似乎 落后于服务器 我不知道可能是什么原因
  • 外键与独立关系 - Entity Framework 5 有改进吗?

    我读过了several http www ladislavmrnka com 2011 05 foreign key vs independent associations in ef 4 文章和问题 https stackoverflow
  • 如何在非控制台应用程序中查看 cout 输出?

    输出到调试窗口似乎相当繁琐 我在哪里可以找到cout如果我正在编写非控制台信息 则输出 Like double i a b cout lt lt b lt lt endl I want to check out whether b is z
  • C++ 函数重载类似转换

    我收到一个错误 指出两个重载具有相似的转换 我尝试了太多的事情 但没有任何帮助 这是那段代码 CString GetInput int numberOfInput BOOL clearBuffer FALSE UINT timeout IN
  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • 方法优化 - C#

    我开发了一种方法 允许我通过参数传入表 字符串 列数组 字符串 和值数组 对象 然后使用这些参数创建参数化查询 虽然它工作得很好 但代码的长度以及多个 for 循环散发出一种代码味道 特别是我觉得我用来在列和值之间插入逗号的方法可以用不同的
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装
  • 无法接收 UDP Windows RT

    我正在为 Windows 8 RT 编写一个 Windows Store Metro Modern RT 应用程序 需要在端口 49030 上接收 UDP 数据包 但我似乎无法接收任何数据包 我已按照使用教程进行操作DatagramSock
  • Oracle Data Provider for .NET 不支持 Oracle 19.0.48.0.0

    我们刚刚升级到 Oracle 19c 19 3 0 所有应用程序都停止工作并出现以下错误消息 Oracle Data Provider for NET 不支持 Oracle 19 0 48 0 0 我将 Oracle ManagedData
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看
  • 当从finally中抛出异常时,Catch块不会被评估

    出现这个问题的原因是之前在 NET 4 0 中运行的代码在 NET 4 5 中因未处理的异常而失败 部分原因是 try finallys 如果您想了解详细信息 请阅读更多内容微软连接 https connect microsoft com

随机推荐

  • 获取合适的VS2017实例进行自主开发扩展

    我正在开发一个 Visual Studio 扩展 以使用从代码窗口中的右键单击上下文菜单调用的自定义命令来替换当前活动 cs 文件中的文本 到目前为止 访问文档是有效的 但如果我启动多个 VS2017 实例 那么我希望在新实例中完成的更改将
  • 在应用程序购买中添加二进制文件

    我已提交新版本的应用程序和新的应用程序购买 苹果有强调新版本的应用程序 但不接受应用程序内购买 应用内购买 新商业模式 我们已开始审核您的应用内购买 但无法继续 因为您提交的应用内购买表明您的应用的业务模式发生了变化 因此 我们需要验证您提
  • 是否有可用于在浮点表示形式之间进行转换的 C++ 库?

    我最近需要解释 DEC 32 位浮点表示 它与 IEEE 浮点表示法的不同之处在于分配给指数和尾数的位数 以下是一堆浮点格式的描述 http www quadibloc com comp cp0201 htm http www quadib
  • docker nginx ERR_NAME_NOT_RESOLVED

    运行 4 个 docker 容器 服务器 客户端 nginx mongo 反向代理 客户端似乎在端口 4200 上工作 我可以看到我的应用程序和路由工作 当尝试注册用户时 我请求将以下 httpclient 发布到名为 myserver 的
  • Excel VBA 宏用于跟踪单独工作表中的更改

    我正在尝试编写一个 VBA 宏来跟踪对单独工作表中工作簿的更改 如果您手动执行此操作 命令顺序为 工具 gt 跟踪更改 gt 突出显示更改 并选择 单独工作表 选项 您必须执行该命令的两次迭代 一次是激活内联跟踪 第二次是将跟踪移动到单独的
  • android:singleLine 的 TextView 不再处于“已弃用”状态?

    我面临 android ellipsize 在 TextView 中不起作用的问题 但要在 android singleLine 上正常工作 我听说 android singleLine 已 弃用 但 Android Developer 的
  • 系统 IO 异常:进程无法访问该文件,因为该文件正在被另一个进程使用 c#

    我已经看到了关于这个问题的几篇文章 我已经实现了所有建议 例如在流写入器和连接对象上使用flush close 方法 使用GC Collect 强制清理 使用using 自动处置 我正在从数据库进行简单的获取操作并写入文本文件 这是我的代码
  • 使用Javascript将所有span标签更改为label标签?

    我想做的 调用卸载函数来更改 span some content span into
  • Rascal 中的布局

    当我导入 Lisra 配方时 import demo lang Lisra Syntax 这将创建语法 layout Whitespace t n r lexical IntegerLiteral 0 9 gt gt 0 9 lexical
  • 使用 GetProcAddress 从 C++ 调用 Delphi DLL:回调函数因参数无效而失败

    我有一个第三方 Delphi DLL 我从 C 调用它 不幸的是 我无法访问 Pascal DLL 代码 并且我不是 Pascal 程序员 没有lib文件 所以我使用GetProcAddress调用许多DLL函数 成功地按值 地址和引用传递
  • WCF 和 HTTP GET

    我的WCF服务公开了这个函数 public SerialNumberInfo GetSerialNumberInfo string serialNumber 有没有办法在我的 WCF 服务上启用 HTTP GET 例子 http local
  • 动态链接和 Python SWIG (C++) 在 C++ 中工作在 python 中失败

    我有一个库 我使用 SWIG 创建了一个 python 包装器 该库本身接受用户提供的函数 这些函数位于动态链接的 so 文件中 目前 我正在处理我自己创建的一个 并设法在 C 中使动态链接正常工作 当我尝试在 python 中运行它时 出
  • Ember.js 路由器入门

    我想在下一个项目中学习使用 Ember js 到目前为止我已经阅读了文档here http emberjs com documentation 但我没有看到有关路由器的解释 然后我读了指南here http emberjs com guid
  • 查找图像中一条线上的像素坐标

    我有一个表示为二维数组的图像 我想获取从点 1 到点 2 的直线上的像素坐标 例如 假设我有一张尺寸为 5x4 的图像 如下图所示 我有一条从坐标点 1 开始的线 0 2 到点 2 4 1 就像下图中的红线一样 所以在这里我想将蓝色像素的坐
  • 如何在 JPQL 中将日期时间转换为日期?

    这段代码有什么问题 Query value Select date ivd trnDatetime as date ivd binNo as bin ivd snNo as sn count ivd invoiceNo as totInvo
  • api 获取请求失败后重新调用 useEffect

    我正在执行 useEffect 以使用 JSON 数据更新状态 但是 获取请求有时会失败 因此如果发生这种情况 我想重新执行 useEffect 挂钩 import React useState useEffect from react i
  • 如何使用注释排除java类在maven中编译

    我已经有一个working解决方案 我可以使用 Maven 指定在使用特定 Maven 配置文件时不编译哪些类 但我想使用通用解决方案并使用注释代替 我目前的解决方案就像
  • 伪元素内容的数据内容中的 Unicode

    我想使用 JQuery 将 unicode 放入 data content 属性中 以便将其用于伪元素内容 但我找不到正确的格式 你如何显示unicode 下面只是显示 x25BC a after content attr data con
  • Vim 从光标上次消失的位置开始

    如何让 Vim 始终从我上次退出给定文件时所在的行开始 将其放入您的 vimrc 中 When editing a file always jump to the last cursor position au BufReadPost if
  • WinForms C# 中优雅的日志窗口

    我正在寻找一种有效的方法来实现 Windows 窗体应用程序的日志窗口 过去我已经使用 TextBox 和 RichTextBox 实现了几个 但我仍然对功能不完全满意 此日志旨在为用户提供各种事件的最新历史记录 主要用于数据收集应用程序