天天看点

C# 检测RichTextBox 实际行数

碰到的问题: 我们的程序需要做文本的行数控制,也就是当文本输入至指定行数时,再增加行数就会出现警告,不能再进行输入了。 最初的解决方法:        因为RichTextBox本身带有Lines属性,所以开始的时候打算直接采用这个属性,然后在TextChanged事件中进行行数控制。但是实际运行时发现这种方法不行。 MSDN上对Lines属性的备注中有如下解释: 该数组中的每个元素成为文本框控件中的一行文本。如果文本框控件的 Multiline 属性设置为 true ,并且文本中出现换行符,则换行符后的文本被添加到该数组的一个新元素中,并显示在另一行上。 根据这个说明,如果用户一直输入文本,不主动输入回车符,则到控件最右边时控件会自动换行,但是它并不会把换行符后的文本被添加到该数组的一个新元素中,也就是说Lines属性的Count值不会变。如下图所示:

C# 检测RichTextBox 实际行数

  其实我想得到的值是4而不是1。 想到的解决方法1: 查阅MSDN,Graphic类中的MeasureString方法可以测量文本的行数,函数原型如下: C# public SizeF MeasureString(

string text,
	Font font,
	SizeF layoutArea,
	StringFormat stringFormat,
	out int charactersFitted,
	out int linesFilled)
           
各个参数的意义可以查阅MSDN,最后一个参数的值就是我们想要的结果。
           
linesFilled
           

类型:System.Int32

字符串中的文本行数。

上图中的实际行数值就是用这种方法测量的。

这种方法实际运行时也有不准的时候,下图所示,原因如下(MeasureString的备注):

MeasureString 方法旨在与个别字符串一起使用,它在字符串前后包括少量额外的空格供突出的标志符号使用。另外,DrawString 方法会调整标志符号镑值以优化显示质量,它显示的字符串可能比 MeasureString 报告的窄。若要获得适合布局中相邻字符串的度量值(例如,实现格式化文本时),请使用 MeasureCharacterRanges 方法或者使用带有 StringFormat 的 MeasureString 方法中的一种,然后传递 GenericTypographic。同样,请确保 Graphics 的 TextRenderingHint 是 AntiAlias。

C# 检测RichTextBox 实际行数

想到的解决方法2:

RichTextBox控件有GetCharIndexFromPosition函数,可以根据一个位置获取位置所在字符序号,可以伪造位置信息,从第一行开始计算位置所在的字符序号,判断是否是文本的最后一个字符,。不过这种方法在一行字符输入满,再输一个就自动换行后,得到的行数也不准确,不过还是比想到的解决方法1要准确些。

C# 检测RichTextBox 实际行数
C# 检测RichTextBox 实际行数
C# 检测RichTextBox 实际行数

想到的解决方法3:

自己计算每个字符的宽度,然后计算换行,这种方法应该是最准确的 。