Автоматическое масштабирование RichTextBox - PullRequest
0 голосов
/ 09 октября 2019

Я пытаюсь использовать RichTextBoxes только для чтения, чтобы показать сгенерированный пользователем текст. Высота текстового поля и элемента управления должна зависеть от содержимого и быть ограничена определенным максимумом; все, что находится за этой точкой, использует полосы прокрутки.

Авторазмер не работает для 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, совершенно неверна - функция помещает ее где-то на 105 пикселей внизось у, когда она на самом деле ближе к 60, что делает текстовое поле примерно вдвое большим, чем должно быть.

Ширина здесь не является проблемой, так как поле начинается с ширины, которой я являюсьустановка его в значение и повторное чтение точки дает тот же результат.

Ответы [ 2 ]

0 голосов
/ 10 октября 2019

WinForm RichtextBox предоставляет событие ContentsResized , которое в сочетании со свойством MinimumSize и свойством MaximumSize допускает автоматическое управление размером.

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;
    }
}
0 голосов
/ 09 октября 2019

Решено.

Я использовал метод 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.
}
...