有人可以解释一下我将如何测量richtextbox控件中的字符串,以便我可以根据其内容自动调整richtextbox控件的大小吗?
谢谢
编辑:
我已经考虑过了,因为如果 RichTextBox 控件中有不同的字体,下面的答案将不起作用,如果,我可以得到richtextbox 控件的左上角坐标,然后得到右下角坐标rtb 中的最后一行文本。这基本上会给我 RichTextBox 控件中字符串的宽度和高度。这可能吗?或者这样做是一个坏主意?
有人可以解释一下我将如何测量richtextbox控件中的字符串,以便我可以根据其内容自动调整richtextbox控件的大小吗?
谢谢
编辑:
我已经考虑过了,因为如果 RichTextBox 控件中有不同的字体,下面的答案将不起作用,如果,我可以得到richtextbox 控件的左上角坐标,然后得到右下角坐标rtb 中的最后一行文本。这基本上会给我 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(Size.Empty)。它是在 Control 类中定义的,如果 RichTextBoxControl 覆盖了属性,则应该为您提供所需的内容。
如果您将 Size.Empty 以外的内容传递给该方法,那么它将使用该值作为最大约束。使用 Size.Empty 意味着潜在的大小是无限的。
您可以通过调用来测量字符串TextRenderer.MeasureText
。
但是,如果文本包含多种字体,这将不起作用。
编辑:您正在寻找GetPositionFromCharIndex
方法。
请注意,如果有多行,则应取每行最后一个字符的 X 坐标的最大值。
我找到了富文本框高度问题的解决方案..我已将其修改为一般用途..
在您的应用程序中创建以下结构......
[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...
添加到巴蒂尼尼的好答案:
背景:我需要测量 RTF 输出高度以渲染到纸上,因为我有自定义动态页眉/页脚,所以我需要控制分页)。
(RichTextBox.GetLineFromCharIndex 因为复杂的 RTF 而让我失望;包括带有自动换行的行和多列表)。
无论如何,一切工作正常,直到其他人使用我的应用程序与可怕的窗口“使文本和其他项目更大或更小”(DPI 设置。) - 简而言之,现在测量更大尺寸的字体它搞砸了页面长度计算。(打印机仍然正确地渲染了文本和列 - 现在只有页面长度全错了。)
只有考虑 DPI 差异的因素失败了,因为简而言之,较大的文本不适合源 RTF tx 和 cellx 值。
无论如何,如果其他人正在做类似的疯狂事情,经过反复试验,我们会为 Bathineni CalculateRichTextHeight 方法提出以下(最终很少)mod:
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))