自动缩放 RichTextBox

Autoscaling RichTextBox

我正在尝试使用只读 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 得到的点是完全错误的 - 该函数将它放在某个地方在 y 轴向下 105px 处,当它实际上接近 60 时,使文本框大约是它应该的两倍大。

宽度似乎不是这里的问题,因为框以我设置的宽度开始,再次读取点会产生相同的结果。

已解决。

我用的是TextRenderer.MeasureText方法。

由于这种方法忽略了一个事实,即很长的行会在 RichTextBox 中接收一个或多个自动换行符,因此我编写了一个函数,通过换行符手动将文本分成任意长度的行,然后测量其中的每一个行以检查它将在 RTB 中使用多少行。

函数如下,以备不时之需:

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 that when coupled with the MinimumSize Property and the 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;
    }
}