所有者绘制文本框以在 WinForms 中使用

Posted

技术标签:

【中文标题】所有者绘制文本框以在 WinForms 中使用【英文标题】:Owner draw TextBox for use in WinForms 【发布时间】:2011-04-08 10:44:37 【问题描述】:

我需要一个精益且平均的 TextBox 解决方案。一个 RichTextBox 太慢了,所以我想走所有者绘图或自定义控件构建的方式。

我需要一个可以处理大文本内容并通过在单词或单个字符周围绘制彩色背景来提供简单突出显示的文本框。重要的是,文本字符串本身不包含为此的标记,而是要标记的单词的索引是单独存储的。相对于文本字符串开头的索引(在谈到 .NET TextBox 时也称为 Text 属性)。

我认为它必须涉及在我自己的控件下绘制文本,因为 Windows 编辑控件将无法执行我需要的操作。

我的应用程序是 Windows 窗体。制作这样一个控件的正确方法是什么,有什么例子吗?

可以在.NET 下进行快速控制吗? (已经假设需要本地 API 调用)。还是用 C++ 做得更好?


附加 1: 我认为这样做的方法正如用户 MarkIsMobile 在 SO 问题 Drawing over a TextBox in .NET Compact Framework 中的回答所描述的那样。看,TextBox 的 OnPaint 并不是很有用,因为 TextBox 是一个相当古怪的控件。 MarkIsMobile 的答案中概述的方法如下:

用您自己的 C# 委托替换默认的 Windows 过程 但仍保持“默认”行为,并调用“OldWindowsProc” 在此之后进行您自己的自定义绘图

我自己还没有尝试过这个,但有兴趣看到更多这样的例子。

还有。我目前的方法是(相同?)通过 NativeWindow 类访问控件并覆盖 WndProc。我只是用一定程度的透明度在文本上覆盖 以创建我所追求的“颜色标记”效果,这实际上效果很好 - 但并不完美。 (有没有办法用位图混合绘制,只对背景着色而不是前景中的文本?)

【问题讨论】:

【参考方案1】:

您无法实际实现自己的 TextBox,编写自己的文本编辑器是一种惩罚。使用现成的东西,比如 ScintillaNET。

编写自己的可滚动标签在某种程度上是可行的。从一个双缓冲面板开始,使用 OnPaint 绘制文本。如果你不实现自动换行,它只会是一个改进,这使得弄清楚从哪里开始绘制非常昂贵,因为你必须在滚动的第一条可见行之前换行所有文本。计算 AutoScrollMinSize 的成本很高,因为您必须扫描整个文本以计算换行符,确保您不必过于频繁地更新 Text。

一般来说,您很有可能只知道为什么 TextBox 这么慢。您可以通过将文本数量限制在人们可以合理地期望阅读的内容来保持它的性能。这并不多。我通过跟踪每个附加文本的长度并在超过 65536 个字符时将其中的一半扔掉来做到这一点。一个不错的整数。

【讨论】:

感谢您的回答。我暂时没有回复内容,因为我有一段时间忙于其他事情,但我稍后会详细说明...

以上是关于所有者绘制文本框以在 WinForms 中使用的主要内容,如果未能解决你的问题,请参考以下文章

C# winforms:将可空类型绑定到其他属性(不是文本)时出错

如何在视频上绘制文本以在 iOS 上显示字幕?

文本格式化文本框以符合时间 vb.net

自定义 WinForms ErrorProvider 以在控件条目中显示其图标

添加垂直线以在列包含文本的日期绘制

OpenGL:绘制矩形后不显示文本