我想知道是否有更好的方法解决这个问题。我想调整标签的大小(垂直)以容纳一定数量的文本。我的标签有一个固定的宽度(在它必须包裹之前大约60个字符宽),大约495像素。字体也是固定大小(12分afaik),但文本不是。
我想要做的是当有“NewLine”或文字必须换行时增加标签高度;这个想法是文本在标签中完全可见。 AutoSize不起作用,因为它会在宽度上增长,而不是在高度上增长。
当然我可以计算NewLines的数量并添加:Newlines * LineHeight,然后-given我设法每行放60个字符,只需分割字符数并根据需要添加尽可能多的LineHeight像素。
我想知道是否有更专业的方法来做到这一点。我的做法太“蹩脚”了吗?
提前致谢。
答案 0 :(得分:91)
Graphics.MeasureString
怎么样,带有接受字符串,字体和最大宽度的重载?这会返回SizeF
,因此您可以对Height
进行四舍五入。
using(Graphics g = CreateGraphics()) {
SizeF size = g.MeasureString(text, lbl.Font, 495);
lbl.Height = (int) Math.Ceiling(size.Height);
lbl.Text = text;
}
答案 1 :(得分:33)
System.Drawing.Graphics有一个MeasureString方法,您可以将其用于此目的。使用带有字符串,字体和int“width”参数的重载;最后一个参数指定字符串允许的最大宽度 - 使用此参数的标签设置宽度。
MeasureString返回一个SizeF对象。使用此返回对象的Height属性设置标签的高度。
注意:要获得用于此目的的Graphics对象,可以调用this.CreateGraphics。
答案 2 :(得分:9)
Graphics.MeasureString()可能会帮助你。
这也是使用Control.CreateGraphics()调用的唯一用例之一!
答案 3 :(得分:5)
Size maxSize = new Size(495, int.MaxValue);
_label.Height = TextRenderer.MeasureText(_label.Text , _label.Font, maxSize).Height;
答案 4 :(得分:2)
这个“答案”是为了将来参考,并且打击AutoSize = true的初始假设意味着它(WinForms标签)的高度永远不会增长。
以下链接显示了AutoSize = true与其他属性(如MaximumSize)的各种影响。根据问题的预期用途,可能适合采用其中一种方法。
答案 5 :(得分:1)
我发布了一个用户控件,它在接受的答案中解决了这个问题: Autoscale Font in a TextBox Control so that its as big as possible and still fits in text area bounds
该控件扩展了RichTextBox。它有一个方法:ScaleFontToFit,它将自动调整字体大小以使所有文本都适合。
整洁的事情是它尊重多线属性。如果它是真的它允许单词包装,否则它不会。
答案 6 :(得分:1)
我想提出一个替代方案,因为它是一个标签,而不仅仅是文本呈现:GetPreferredSize
。我尝试了马克的回答,但问题是它几乎有效:标签在文本周围有一些“填充”,这需要在 {{1} 的 width
值中考虑}}。我找不到任何明显的方法来获得这个填充。在挖掘时,我发现 this answer 海报建议将 MeasureString
设置为 FlatStyle
。这有效,但不幸的是打破了我希望它成为 System
的 TextAlign
。
我查看了 MiddleLeft
代码,发现了 Label
,它考虑了所有奇怪的设置(GetPreferredSize
、FlatStyle
等)并且可以为您提供每个案例的正确结果。所以你可以代替UseCompatibleTextRendering
g.MeasureString(text, lbl.Font, 495);
甚至像这样,因为标签大小已经知道了:
lbl.GetPreferredSize(new Size(495, 0));
如果您想知道,0 和 1 将被视为 lbl.GetPreferredSize(new Size(lbl.Width, 0));
。
我不知道 int.MaxValue
是什么时候引入的,所以早在 2008 年马克写他的答案时,上述内容可能并不相关。但是,如果您在 2021 年仍然需要类似的东西,GetPreferredSize
可能会稍微方便一点 - 它返回 GetPreferredSize
而不是 Size
。
答案 7 :(得分:0)
60个字符可能对您的测试文本有效,但并非所有字符都具有相同的宽度。例如,比较
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
和
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
它们都有60个字符,但宽度却大不相同。
答案 8 :(得分:0)
使用TextRenderer类测量字符串(比如Marc的响应)而不是完成创建Graphics对象的工作是否有任何缺点?
答案 9 :(得分:0)
根据this article,如果要使用Windows窗体控件进行最终输出,则应使用TextRenderer。 TextRenderer和Graphics.MeasureString将给出不同的结果,因此请使用与您的最终输出模式匹配的结果。
答案 10 :(得分:0)
在某些情况下,你必须使用紧凑框架,它没有任何MeasureString()的覆盖方法,你可以考虑自己计算高度。
private int YukseklikAyarla(string p, Font font, int maxWidth)
{
int iHeight = 0;
using (Graphics g = CreateGraphics())
{
var sizes = g.MeasureString(p, font); // THE ONLY METHOD WE ARE ALLOWED TO USE
iHeight = (int)Math.Round(sizes.Height);
var multiplier = (int)Math.Round((double)sizes.Width) / maxWidth; // DIVIDING THE TEXT WIDTH TO SEE HOW MANY LINES IT CAN HAS
if (multiplier > 0)
{
iHeight = (int)(iHeight * (multiplier + 1)); // WE ADD 1 HERE BECAUSE THE TEXT ALREADY HAS A LINE
}
}
return iHeight;
}
答案 11 :(得分:0)
尽管它是一个古老的话题,但认为它可以帮助新访客。
在C#中,您可以使用control.width