为什么不'MeasureText工作正常
本文关键字:工作 MeasureText 为什么不 | 更新日期: 2023-09-27 18:16:43
我想测量给定可用画布宽度的文本的高度。我传入的文本很长,我知道会换行。为此,我调用以下语句:
using System.Windows.Forms;
...
string text = "Really really long text that is sure to wrap...";
Font font = new Font("Arial", 14);
Size canvas = new Size(1100, 850);
Size size = TextRenderer.MeasureText(text, font, canvas);
无论我传递什么给canvas,它总是返回14给size.Height
。
我错过了一些简单的东西吗?
请按如下所示使用TextFormatFlags度量参数:
Size size = TextRenderer.MeasureText(text, font, canvas, TextFormatFlags.WordBreak);
DimitryG的解决方案似乎工作得很好,但只有当没有足够大的单词来填充超过一整行时。如果存在这样的词,则宽度将大于建议的宽度。在这种情况下有标志TextFormatFlags.EndEllipsis
,但是我没有设法以某种方式组合标志,所以输出是正确的(如果我使用TextFormatFlags.WordEllipsis | TextFormatFlags.WordBreak
,宽度是正确的,但是高度在Word省略发生时不更新,这意味着大字将被修剪,但高度将与未修剪相同)。我还尝试了标志TextFormatFlags.EndEllipsis
,但没有结果。
所以,在有人说清楚之前,我建议使用TextBox
进行换行,然后将TextBox
中的行数乘以Font
的高度。
int MeasureMultilineTextHeigh(string text, Font font, int proposedWidth)
{
// Exception handling.
TextBox textBox = new TextBox()
{
Multiline = true,
BorderStyle = BorderStyle.None,
Width = proposedWidth,
Font = font,
Text = text,
};
int lineCount = textBox.GetLineFromCharIndex(int.MaxValue) + 1;
int fontHeight = TextRenderer.MeasureText("X", font).Height;
return lineCount * fontHeight;
}
然而,这种方法有一个问题:当且仅当TextBox
的Multiline
属性设置为true
时,每个Font
将有自己的左右填充。请参阅stackoverflow.com的问题和social.msdn.microsoft.com的问题了解更多细节。因此,这意味着在某些情况下,返回值可能比预期的要大。要解决这个问题,您可以使用SetPadding
函数删除填充(您可以在第一个问题中找到作为答案的方法),代码:
private const int EM_SETRECT = 0xB3;
[DllImport(@"User32.dll", EntryPoint = @"SendMessage", CharSet = CharSet.Auto)]
private static extern int SendMessageRefRect(IntPtr hWnd, uint msg, int wParam, ref RECT rect);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public readonly int Left;
public readonly int Top;
public readonly int Right;
public readonly int Bottom;
private RECT(int left, int top, int right, int bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}
public RECT(Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom) { }
}
public void SetPadding(TextBox textBox, Padding padding)
{
var rect = new Rectangle(padding.Left, padding.Top, textBox.ClientSize.Width - padding.Left - padding.Right, textBox.ClientSize.Height - padding.Top - padding.Bottom);
RECT rc = new RECT(rect);
SendMessageRefRect(textBox.Handle, EM_SETRECT, 0, ref rc);
}
int MeasureMultilineTextHeigh(string text, Font font, int proposedWidth)
{
// Exception handling.
TextBox textBox = new TextBox()
{
Multiline = true,
BorderStyle = BorderStyle.None,
Width = proposedWidth,
Font = font,
};
SetPadding(textBox, Padding.Empty);
textBox.Text = text;
int lineCount = textBox.GetLineFromCharIndex(int.MaxValue) + 1;
int fontHeight = TextRenderer.MeasureText("X", font).Height;
return lineCount * fontHeight;
}
需要使用语句:
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;
我希望这对你有帮助。