请问如何测量richtextbox控件中字符串的大小,以便根据其内容自动调整rich textbox控件的大小?
谢谢。
编辑:
我已经考虑过了,由于下面的答案无法处理RichTextBox控件中存在不同字体的情况,那么如果我可以获取richtextbox控件的左上坐标,然后获取最后一行文本的右下坐标,这将基本上给出RichTextBox控件中字符串的宽度和高度。这是可能的吗?还是这样做是个坏主意?
请问如何测量richtextbox控件中字符串的大小,以便根据其内容自动调整rich textbox控件的大小?
谢谢。
编辑:
我已经考虑过了,由于下面的答案无法处理RichTextBox控件中存在不同字体的情况,那么如果我可以获取richtextbox控件的左上坐标,然后获取最后一行文本的右下坐标,这将基本上给出RichTextBox控件中字符串的宽度和高度。这是可能的吗?还是这样做是个坏主意?
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
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;
GetPreferredSize(new Size(width, 0))
来调用它,然后从返回的 Size 中获取高度。 - Rémi我找到了解决富文本框高度问题的方法... 我已经修改了它以供通用使用...
在您的应用程序中创建以下结构体....
[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...
补充一下bathineni的好答案:
背景:我需要测量RTF输出高度以便渲染到纸上,因为我有自定义动态页面页眉/页脚,所以我需要控制分页)。
(由于复杂的RTF,包括带换行符的行和多列表格,RichTextBox.GetLineFromCharIndex让我失望了。)
总之,一切都很顺利,直到有人使用我的应用程序时出现了可怕的Windows“使文本和其他项目变大或变小”(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))
您可以通过调用TextRenderer.MeasureText
来测量字符串。
但是,如果文本包含多种字体,则此方法将无法正常工作。
编辑:您需要使用GetPositionFromCharIndex
方法。
请注意,如果有多行文本,您应该取每行最后一个字符的X坐标的最大值。
TextRenderer.MeasureText
并дёҚдјҡз»ҳеҲ¶д»»дҪ•дёңиҘҝпјҢе®ғеҸӘжҳҜиҝ”еӣһж–Үжң¬еңЁеғҸзҙ дёӯзҡ„еӨ§е°ҸгҖӮ - SLaks
ContentsResized
和e.NewRectangle
对我很有帮助。其他常见的方法,如AutoSize
、GetPreferredSize
似乎不能很好地适用于RichTextBox
。 - Ben Challenor