在RichTextBox控件中测量字符串

时间:2010-03-02 16:55:22

标签: c# winforms richtextbox autoresize measure

有人可以解释我如何测量richtextbox控件中的字符串,以便我可以根据其内容自动调整richtextbox控件的大小吗?

谢谢

编辑:

我已经考虑过了,因为如果RichTextBox控件中有不同的字体,下面的答案将不起作用,如果,我可以得到richtextbox控件的左上角坐标然后得到底部 - rtb内最后一行文字的右边坐标。这基本上会给我RichTextBox控件中字符串的宽度和高度。这可能吗?或者这样做是不是一个坏主意?

6 个答案:

答案 0 :(得分:7)

将以下代码放入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

答案 1 :(得分:3)

尝试拨打GetPreferredSize(Size.Empty)。它在Control类中定义,如果RichTextBoxControl覆盖属性,则应该为您提供所需的内容。

如果将除Size.Empty之外的其他内容传递给方法,则它将使用该值作为最大约束。使用Size.Empty意味着潜在的大小是无限制的。

答案 2 :(得分:2)

假设某人正在输入控件,您可以在每次输入字符时使用一个事件(增量计数器),并在删除时减少。这会给你一个真正的计数。

编辑:

你试过这个来调整身高吗?

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;

或者您可以使用宽度执行此操作:

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

SizeF f = g.MeasureString(richTextBox1.Text, richTextBox1.Font);
richTextBox1.Width = (int)(f.Width)+5;

答案 3 :(得分:0)

您可以通过调用TextRenderer.MeasureText来衡量字符串。

但是,如果文本包含多种字体,则无法使用。

编辑:您正在寻找GetPositionFromCharIndex方法 请注意,如果有多行,则应采用每行上最后一个字符的X坐标的最大值。

答案 4 :(得分:0)

我找到了Rich文本框高度问题的解决方案..我已将其修改为一般用途..

在您的应用程序中创建以下结构....

[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 ...

答案 5 :(得分:0)

加入bathineni的绝佳答案:

背景:我需要测量RTF输出高度以便渲染到纸上,因为我需要自定义动态页眉/页脚来控制分页。

(RichTextBox.GetLineFromCharIndex让我失望,因为复杂的RTF;包括带有wordwrap的行和多列表。)

无论如何一切都运转良好,直到有人用我的应用程序与可怕的窗户"使文字和其他项目更大或更小" (DPI设置。) - 简而言之,现在测量更大尺寸的字体,它搞砸了页面长度计算。 (打印机仍然正确地呈现文本和列 - 只有页面长度现在都是错误的。)

仅将DPI差异分解失败,因为较短的较大文本并不适合源RTF tx和cellx值。

无论如何,如果其他人正在做类似的疯狂事情,试验和错误的一些事情提出了以下(最终很少)mods到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(pix?) )还记得重新考虑除数。 即在我的情况下:

lines = height / (int)(16 * (dpix / 96))