Подтвердить что ты не робот

Autofit WinForms RichTextBox для его содержимого

Кто-нибудь знает, как я могу динамически изменять размер элемента управления RichTextBox до его содержимого?

4b9b3361

Ответ 1

Я думаю, что я слишком поздно, но взгляните на этот

Это всего две строки кода:

private void rtb_ContentsResized(object sender, ContentsResizedEventArgs e)
{
    ((RichTextBox)sender).Height = e.NewRectangle.Height + 5;
}

Ответ 2

Снова приняв фиксированный шрифт, вы можете сделать что-то вроде:

using (Graphics g = CreateGraphics())
{
    richTextBox.Height = (int)g.MeasureString(richTextBox.Text,
        richTextBox.Font, richTextBox.Width).Height;
}

Ответ 3

Это какая-то боль - С# RichTextBox часто расстраивает работу. Вы пытаетесь размер коробки достаточно большой, чтобы держать ее содержимое без полосы прокрутки?

Если RichTextBox имеет постоянный шрифт, вы можете использовать TextRenderer.MeasureText, чтобы просто измерить требуемый размер и передать ширину поля в качестве ограничения.

Событие ContentsResized предоставляет вам ContentResizedEventsArgs, который дает вам NewRectangle, который сообщает вам, насколько велика область текста. Но он срабатывает только тогда, когда текст изменяется, что не так полезно, если вы просто хотите измерить существующий richtextbox (хотя вы, вероятно, могли бы просто сделать что-то взломанное, как установить текст окна самому себе, вызывая это событие).

Также существует множество вызовов Win32 api, например, с помощью EM_GETLINECOUNT (http://ryanfarley.com/blog/archive/2004/04/07/511.aspx) и т.д.

Ответ 4

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

Итак, вот так:

RichTextBox rtb = new RichTextBox();
rtb.Text = "this is some text";
rtb.Font = new Font("Franklin Gothic Medium Cond", 10, FontStyle.Regular);

Label fittingLabel = new Label();
fittingLabel.Text = rtb.Text;
fittingLabel.Font = rtb.Font;
fittingLabel.AutoSize = true;

//Not sure if it necessary to add the label to the form for it to autosize...
fittingLabel.Location = new Point(-1000,-1000);
this.Controls.Add(fittingLabel);

rtb.Width = fittingLabel.Width;

this.Controls.Remove(fittingLabel);

Ответ 5

см. ссылку

вы просто используете ContentsResized Событие такое же:

private void rtb_ContentsResized(object sender, ContentsResizedEventArgs e)
{
      ((RichTextBox)sender).Height = e.NewRectangle.Height + 5;
}

Ответ 6

Я нашел решение для проблем с большим количеством текстовых полей. Я изменил его для общего использования.

Создайте следующие структуры в своем приложении....

[StructLayout(LayoutKind.Sequential)]
    public struct RECT {
        public Int32 left;
        public Int32 top;
        public Int32 right;
        public Int32 bottom;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct SCROLLBARINFO {
        public Int32 cbSize;
        public RECT rcScrollBar;
        public Int32 dxyLineButton;
        public Int32 xyThumbTop;
        public Int32 xyThumbBottom;
        public Int32 reserved;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        public Int32[] rgstate;
    }

Создайте следующие частные переменные в своем классе для формы (где вам когда-либо нужно рассчитать высоту текста)

private UInt32 SB_VERT = 1;
        private UInt32 OBJID_VSCROLL = 0xFFFFFFFB;

        [DllImport("user32.dll")]
        private static extern
            Int32 GetScrollRange(IntPtr hWnd, UInt32 nBar, out Int32 lpMinPos, out Int32 lpMaxPos);

        [DllImport("user32.dll")]
        private static extern
            Int32 GetScrollBarInfo(IntPtr hWnd, UInt32 idObject, ref SCROLLBARINFO psbi);

Добавьте следующий метод в свой класс для формы

private int CalculateRichTextHeight(string richText) {
            int height = 0;
            RichTextBox richTextBox = new RichTextBox();
            richTextBox.Rtf = richText;
            richTextBox.Height = this.Bounds.Height;
            richTextBox.Width = this.Bounds.Width;
            richTextBox.WordWrap = false;
            int nHeight = 0;
            int nMin = 0, nMax = 0;

            SCROLLBARINFO psbi = new SCROLLBARINFO();
            psbi.cbSize = Marshal.SizeOf(psbi);

            richTextBox.Height = 10;
            richTextBox.ScrollBars = RichTextBoxScrollBars.Vertical;

            int nResult = GetScrollBarInfo(richTextBox.Handle, OBJID_VSCROLL, ref psbi);
            if (psbi.rgstate[0] == 0) {
                GetScrollRange(richTextBox.Handle, SB_VERT, out nMin, out nMax);
                height = (nMax - nMin);
            }

            return height;
        }

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

Вы можете играть с WordWrap в зависимости от вашего требования...

Ответ 7

Намного проще использовать GetPreferredSize, как описано в этом ответе. Затем вам не нужно ждать события ContentResized.