有人可以解释我如何测量richtextbox控件中的字符串,以便我可以根据其内容自动调整richtextbox控件的大小吗?
谢谢
编辑:
我已经考虑过了,因为如果RichTextBox控件中有不同的字体,下面的答案将不起作用,如果,我可以得到richtextbox控件的左上角坐标然后得到底部 - rtb内最后一行文字的右边坐标。这基本上会给我RichTextBox控件中字符串的宽度和高度。这可能吗?或者这样做是不是一个坏主意?
答案 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))