我正在尝试使用只读RichTextBoxes来显示用户生成的文本。文本框和控件的高度应取决于内容,并限制为一定的最大值,超出此点的任何内容都将使用滚动条。
[AutoSize似乎不适用于RTB
public void Rescale()
{
Point pt = rtbComment.GetPositionFromCharIndex(rtbComment.Text.Length);
int height = rtbComment.GetPositionFromCharIndex(rtbComment.Text.Length).Y + (int)rtbComment.SelectionFont.GetHeight();
if (height > 250)
height = 250;
this.Size = new System.Drawing.Size(616, height + 50);
rtbComment.Size = new System.Drawing.Size(614, height);
}
这对于简短的注释或带有少量文本和许多换行符的注释绝对适用,但对于分成约4行的较长的一线代码,我从GetPositionFromCharIndex得到的要点全都是错误的-函数将其放置在向下105px处在y轴上实际上接近60时,使文本框大约是预期的两倍。
宽度在这里似乎不是问题,因为该框以我将其设置为的宽度开始,再次读取该点会产生相同的结果。
已解决。
我使用了TextRenderer.MeasureText方法。
由于此方法忽略了很长的行将在RichTextBox中接收一个或多个自动换行符的事实,因此我编写了一个函数,该函数可以通过换行符将文本手动拆分为任意长度的行,然后测量每行以检查实时出价会使用多少行。
这里是功能,万一有人需要它:
public int getLines(string comment)
{
int height_ln = 0;
string[] lines;
//split into lines based on linebreaks
if (comment.Contains("\n"))
{
lines = comment.Split('\n');
}
else
{
lines = new string[1];
lines[0] = comment;
}
//check each line to see if it'll receive automatic linebreaks
foreach(string line in lines)
{
int text_width = TextRenderer.MeasureText(line, rtbKommentar.Font).Width;
double text_lines_raw = (double)text_width / 1400; //1400 is the width of my RichTextBox
int text_lines = 0;
if (line.Contains("\r")) //Please don't call me out on this, I'm already feeling dirty
text_lines = (int)Math.Floor(text_lines_raw);
else
text_lines = (int)Math.Ceiling(text_lines_raw);
if (text_lines == 0)
text_lines++;
height_ln += text_lines;
}
return height_ln; //this is the number of lines required, to adjust the height of the RichTextBox I need to multiply it by 15, which is the font's height.
}
WinForm RichtextBox公开了ContentsResized Event,当与MinimumSize Property和MaximumSize Property结合使用时,可以自动调整大小。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
rtbComment.MinimumSize = new Size(250, 200);
rtbComment.MaximumSize = new Size(250, 400);
rtbComment.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical;
rtbComment.ContentsResized += rtbComment_ContentResized;
}
private void rtbComment_ContentResized(object sender, ContentsResizedEventArgs e)
{
rtbComment.Size = e.NewRectangle.Size;
}
}