【c#】关于设置RichTextBox背景透明+无光标只读状态

本文介绍如何通过继承RichTextBox组件来自定义一个背景透明、只读且无鼠标光标的文本展示框,并提供了详细的实现步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在设置一个软件的RichTextBox的时候,需要一个背景透明,不可编辑的文本展示框,而且还要向文本框中不停地追加数据,所以我选择修改winform自带的richtextbox组件。

首先,我们先新建一个自定义组件,继承与RichTextBox,在构造函数中添加双缓冲避免组件闪烁:

        public DsAlphaRichTextBox()
        {
            InitializeComponent();

            this.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(this, true, null);
        }

并重写一个函数,用于将整个组件设置成为背景透明的:

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x20;
                return cp;
            }
        }

接着,设置组件的Readonly为true,设置为只读状态,但是组件中的光标还是存在的,因此,我们需要继续重写一个函数,将光标去除:

首先,在构造函数中,添加this.Cursor = Cursors.Arrow;

然后,重写函数:

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x7 || m.Msg == 0x201 || m.Msg == 0x202 || m.Msg == 0x203 || m.Msg == 0x204 || m.Msg == 0x205 || m.Msg == 0x206 || m.Msg == 0x0100 || m.Msg == 0x0101)
            {
                return;
            }
            base.WndProc(ref m);
        }
这样,我们自定义的透明,只读,无鼠标光标的RichTextBox组件就完成了。

### C# 中 TextBox 添加数据时导致程序卡死的解决方案 在 C# 开发中,当向 `TextBox` 控件频繁追加大量数据时,可能会因为主线程(UI 线程)被长时间占用而引起界面无响应甚至卡死的情况。这通常发生在多线程环境中,尤其是从后台线程更新 UI 组件时未能正确处理线程同步问题。 以下是几种有效的解决方法: --- #### 1. 使用 `SuspendLayout` 和 `ResumeLayout` 为了提高性能并减少重绘操作的影响,可以在批量更新 `TextBox` 数据时临时暂停布局计算: ```csharp textBox.SuspendLayout(); // 暂停布局 try { foreach (var line in lines) { textBox.AppendText(line + Environment.NewLine); } } finally { textBox.ResumeLayout(true); // 恢复布局并强制刷新 } ``` 此方法减少了每次追加文本后的即时渲染次数,从而提升了效率[^1]。 --- #### 2. 利用异步任务 (`Task`) 更新 UI 如果数据来源于耗时操作或后台线程,则建议通过异步方式来分离业务逻辑与 UI 渲染过程。例如: ```csharp private async void AppendDataAsync(IEnumerable<string> dataLines) { await Task.Run(() => { StringBuilder sb = new StringBuilder(); foreach (string line in dataLines) { sb.AppendLine(line); } // 返回到 UI 线程执行实际附加动作 Action updateAction = () => textBox.AppendText(sb.ToString()); if (textBox.InvokeRequired) { textBox.Invoke(updateAction); } else { updateAction(); } }); } ``` 这种方式不仅避免了阻塞主线程,还优化了大数据量拼接的过程[^2]。 --- #### 3. 替换为 `RichTextBox` 并启用只读模式 对于需要展示海量日志信息的情形,可考虑使用功能更强的 `RichTextBox` 控件代替普通的 `TextBox`。同时将其设为只读状态以降低编辑开销: ```csharp richTextBox.ReadOnly = true; richTextBox.SelectionStart = richTextBox.TextLength; richTextBox.ScrollToCaret(); richTextBox.AppendText(dataLine + Environment.NewLine); ``` 此外还可以配合虚拟化技术或者分页加载策略进一步提升流畅度[^3]。 --- #### 4. 减少不必要的属性访问 连续调用诸如 `.Text`, `.SelectedText` 这样的成员会触发内部重新绘制整个控件的行为,因此应当尽量一次性获取所需值后再做后续处理;另外也可以尝试锁定区域范围内的更改通知机制: ```csharp int startIdx = textBox.Text.Length; textBox.AppendText(newContent); textBox.Select(startIdx, newContent.Length); textBox.ScrollToCaret(); ``` 上述代码片段展示了如何精确控制光标位置以及滚动行为而不影响整体表现效果[^4]。 --- ### 结论 面对 C# 应用程序里因频繁修改 `TextBox` 导致的卡顿现象,开发者可以根据具体情况选择合适的技术手段加以应对。无论是借助于高级别的容器特性还是深入挖掘底层原理,最终目标都是保障用户体验的同时维持系统的稳定性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值