有谁知道如何动态调整 RichTextBox 控件的大小以适应其内容?
6 回答
我想我为时已晚,但看看这个
这只是两行代码:
private void rtb_ContentsResized(object sender, ContentsResizedEventArgs e)
{
((RichTextBox)sender).Height = e.NewRectangle.Height + 5;
}
再次假设固定字体,您可以执行以下操作:
using (Graphics g = CreateGraphics())
{
richTextBox.Height = (int)g.MeasureString(richTextBox.Text,
richTextBox.Font, richTextBox.Width).Height;
}
这有点痛苦——使用 C# RichTextBox 经常令人沮丧。您是否尝试将框的大小设置为足够大以容纳其内容而无需任何滚动条?
如果 RichTextBox 具有恒定字体,则可以使用 TextRenderer.MeasureText 简单地测量所需的大小,并将框的宽度作为约束传入。
ContentsResized 事件给你一个 ContentsResizedEventsArgs,它给你一个 NewRectangle,告诉你文本区域有多大。但它仅在文本更改时触发,如果您只是想测量现有的richtextbox(尽管您可能只是做一些hacky,例如将框的文本设置为自身,触发此事件)。
还有一堆 Win32 api 调用,比如使用 EM_GETLINECOUNT ( http://ryanfarley.com/blog/archive/2004/04/07/511.aspx ) 等。
一个非常便宜的解决方案(一个可能充满问题的解决方案)是同时使用相同字体和大小的文本填充自动调整标签,然后只需将标签的宽度复制到 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's 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);
我找到了富文本框高度问题的解决方案..我已将其修改为一般用途..
在您的应用程序中创建以下结构......
[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...
如本答案所述,使用GetPreferredSize更容易。然后您无需等待 ContentsResized 事件。