根据 Winforms/C# 中的文本量和字体大小确定标签大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/388937/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Determine Label Size based upon amount of text and font size in Winforms/C#
提问by Martin Marconcini
I'd like to know if there's a better approach to this problem. I want to resize a label (vertically) to accomodate certain amount of text. My label has a fixed width (about 60 chars wide before it must wrap), about 495 pixels. The font is also a fixed size (12points afaik), but the text is not.
我想知道是否有更好的方法来解决这个问题。我想(垂直)调整标签大小以容纳一定数量的文本。我的标签有一个固定的宽度(在它必须换行之前大约 60 个字符宽),大约 495 像素。字体也是固定大小(12 点 afaik),但文本不是。
What I want to do is increase the Label Height when there's a "NewLine" or the text must wrap; the idea is that the text is fully visible in the label. The AutoSize doesn't work because it will grow in width, not in height.
我想要做的是在出现“NewLine”或文本必须换行时增加标签高度;这个想法是文本在标签中完全可见。AutoSize 不起作用,因为它会增加宽度,而不是高度。
Of course I could count the number of NewLines and add: Newlines * LineHeight, and then -given that I manage to put 60 chars per line, just divide the number of chars and add as many LineHeight pixels as needed.
当然,我可以计算 NewLines 的数量并添加:Newlines * LineHeight,然后 - 假设我设法每行放置 60 个字符,只需除以字符数并根据需要添加尽可能多的 LineHeight 像素。
I was wondering if there was a more professional way to do it. Is my approach too "lame" ?
我想知道是否有更专业的方法来做到这一点。我的方法是不是太“蹩脚”了?
Thanks in advance.
提前致谢。
采纳答案by Marc Gravell
How about Graphics.MeasureString
, with the overload that accepts a string, the font, and the max width? This returns a SizeF
, so you can round round-off the Height
.
怎么样Graphics.MeasureString
,用接受字符串、字体和最大宽度的重载?这将返回 a SizeF
,因此您可以四舍五入Height
。
using(Graphics g = CreateGraphics()) {
SizeF size = g.MeasureString(text, lbl.Font, 495);
lbl.Height = (int) Math.Ceiling(size.Height);
lbl.Text = text;
}
回答by Quibblesome
Graphics.MeasureString() will probably help you.
Graphics.MeasureString() 可能会帮助你。
This is also one of the only usecases for using the Control.CreateGraphics() call!
这也是使用 Control.CreateGraphics() 调用的唯一用例之一!
回答by MusiGenesis
System.Drawing.Graphics has a MeasureString method that you can use for this purpose. Use the overload that takes a string, a font, and an int "width" parameter; this last parameter specifies the maximum width allowed for the string - use the set width of your label for this parameter.
System.Drawing.Graphics 具有可用于此目的的 MeasureString 方法。使用带有字符串、字体和 int "width" 参数的重载;最后一个参数指定字符串允许的最大宽度 - 使用您标签的设置宽度作为此参数。
MeasureString returns a SizeF object. Use the Height property of this returned object to set the height of your label.
MeasureString 返回一个 SizeF 对象。使用此返回对象的 Height 属性设置标签的高度。
Note: to get a Graphics object for this purpose, you can call this.CreateGraphics.
注意:要为此目的获取 Graphics 对象,您可以调用 this.CreateGraphics。
回答by Yuliy
Well the 60 chars might be valid for your test text, but not all characters have the same width. For instance, compare
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
and
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
那么 60 个字符可能对您的测试文本有效,但并非所有字符都具有相同的宽度。例如,比较
llllllllllllllllllllllllllllllllllllllllllllllllllllllllll
和
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
They both have 60 characters, and yet have vastly differing widths.
它们都有 60 个字符,但宽度却大不相同。
回答by jean
Is there any downside to using the TextRendererclass to measure the string (like in Marc's response) instead of going through the work to create a Graphics object, etc?
使用TextRenderer类来测量字符串(如在 Marc 的响应中)而不是通过工作来创建 Graphics 对象等有什么缺点吗?
回答by jean
This "answer" is for future reference and to combat the initial assumption that AutoSize = true implies that it (a WinForms label) will never grow in height.
这个“答案”供将来参考,并与 AutoSize = true 暗示它(WinForms 标签)永远不会增加高度的初始假设作斗争。
The following link shows the various effects of AutoSize = true with other properties such as MaximumSize. Depending upon the expected use of the question it may be appropriate to follow one of these approaches.
以下链接显示了 AutoSize = true 与其他属性(如 MaximumSize)的各种效果。根据问题的预期用途,遵循这些方法之一可能是合适的。
回答by blak3r
I posted a user control which solves this problem in the accepted answer here: Autoscale Font in a TextBox Control so that its as big as possible and still fits in text area bounds
我在这里发布了一个用户控件,它在此处接受的答案中解决了这个问题: Autoscale Font in a TextBox Control,使其尽可能大并且仍然适合文本区域边界
The control extends RichTextBox. It has a method: ScaleFontToFit that will automatically resize the font to make all the text fit.
该控件扩展了 RichTextBox。它有一个方法:ScaleFontToFit,它会自动调整字体大小以适应所有文本。
Neat thing is it respects the multiline property. If it's true it allows words to wrap, Otherwise it doesn't.
整洁的事情是它尊重多行属性。如果它是真的,它允许单词换行,否则它不会。
回答by Hacko
Size maxSize = new Size(495, int.MaxValue);
_label.Height = TextRenderer.MeasureText(_label.Text , _label.Font, maxSize).Height;
回答by Barry Keller
According to this articleyou should use TextRenderer if you are going to use a Windows Form control for the final output. TextRenderer and Graphics.MeasureString will give different results, so use the one that matches your final mode of output.
根据这篇文章,如果您打算将 Windows 窗体控件用于最终输出,则应该使用 TextRenderer。TextRenderer 和 Graphics.MeasureString 将给出不同的结果,因此请使用与您的最终输出模式相匹配的结果。
回答by Do?a Gen?er
In some cases where you must use compact framework, which does not have any override methods for MeasureString(), you might consider calculating the height by yourself.
在某些必须使用紧凑框架的情况下,它没有 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;
}