Измерение строки внутри элемента управления RichTextBox - PullRequest
9 голосов
/ 02 марта 2010

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

Спасибо

Edit:

Я думал об этом, и поскольку приведенный ниже ответ не будет работать, если в элементе управления RichTextBox есть разные шрифты, что, если, я мог бы получить верхние левые координаты элемента управления richtextbox и затем получить правые координаты самой последней строки текста внутри rtb. По сути, это даст мне ширину и высоту строки внутри элемента управления RichTextBox. Это возможно? Или это плохая идея сделать это таким образом?

Ответы [ 6 ]

7 голосов
/ 29 апреля 2011

Введите следующий код в событие ContentsResized:

Private Sub rtb_ContentsResized(ByVal sender As Object, ByVal e As System.Windows.Forms.ContentsResizedEventArgs) Handles txtQuestion.ContentsResized
        Dim h = e.NewRectangle.Height, w = e.NewRectangle.Width
        h = Math.Max(h, sender.Font.Height)
        h = Math.Min(h, Me.ClientSize.Height - 10 - sender.Top)
        h += sender.Height - sender.ClientSize.Height + 1
        sender.Height = h
End Sub
3 голосов
/ 02 марта 2010

Попробуйте позвонить GetPreferredSize (Size.Empty) . Он определен в классе Control, и если переопределенное свойство RichTextBoxControl, должно дать вам то, что вы ищете.

Если вы передадите в метод что-то отличное от Size.Empty, он будет использовать это значение в качестве максимального ограничения. Использование Size.Empty означает, что потенциальный размер не ограничен.

2 голосов
/ 02 марта 2010

Предполагая, что кто-то печатает в элементе управления, вы можете использовать событие для запуска при каждом вводе символа (счетчик приращений) и уменьшения при его удалении. Это даст вам истинный счет.

Edit:

Вы пробовали это отрегулировать высоту?

richTextBox1.Height = (int)(1.5 * richTextBox1.Font.Height) + richTextBox1.GetLineFromCharIndex(richTextBox1.Text.Length + 1) * richTextBox1.Font.Height + 1 + richTextBox1.Margin.Vertical;

richTextBox1.SelectionStart = 0;

richTextBox1.SelectionStart = richTextBox1.Text.Length;

Или вы можете сделать это, используя Width:

Graphics g = Graphics.FromHwnd(richTextBox1.Handle);

SizeF f = g.MeasureString(richTextBox1.Text, richTextBox1.Font);
richTextBox1.Width = (int)(f.Width)+5;
0 голосов
/ 17 октября 2014

Добавьте к великому ответу батинени:

Справочная информация. Мне нужно было измерить высоту вывода RTF для рендеринга на бумагу, и поскольку у меня есть настраиваемые динамические верхние / нижние колонтитулы, мне нужно было управлять страницей).

(RichTextBox.GetLineFromCharIndex подвел меня из-за сложного RTF; включая строки и таблицы из нескольких столбцов с переносом слов).

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

Сбой только разницы в факторинге DPI, так как короче, больший текст не вписывался должным образом в исходные значения RTF tx и cellx.

Так или иначе, в случае, если другие делают подобные сумасшедшие вещи, немного проб и ошибок придумали следующие (в конечном итоге очень немногие) моды для метода bathineni CalculateRichTextHeight:

RichTextBox richTextBox = new RichTextBox();     // same as original
int dpix = richTextBox.CreateGraphics().DpiX;    // get dpi
richTextBox.WordWrap = true;                     // I needed this, you many not
  // ... set size etc - same as original answer
richTextBox.Scale(new System.Drawing.SizeF(dpix / 96, dpix / 96));  // scale RTB
  // ...
  // 96? my original calculations based on windows default 96dpi settings.

Кажется, что в противном случае неясный Control.Scale (sizef) действительно полезен для чего-то.

Примечание: если при преобразовании результатов в фактические напечатанные строки (в моем случае все мои \ pard были "\ sl-240 \ slmult0", что соответствует 16 (пикселям?) На строку), также не забудьте перефакторизовать делитель , т.е. в моем случае:

lines = height / (int)(16 * (dpix / 96))
0 голосов
/ 23 февраля 2012

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

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

[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 в зависимости от ваших требований ...

0 голосов
/ 02 марта 2010

Вы можете измерить строку, вызвав TextRenderer.MeasureText.

Однако, если текст содержит несколько шрифтов, это не будет работать.

РЕДАКТИРОВАТЬ : Вы ищете метод GetPositionFromCharIndex.
Обратите внимание, что если имеется несколько строк, вы должны взять максимум координат X последнего символа в каждой строке.

...