我正在试图找出一种自动调整其中包含文字的Rectangle
的好方法。我基本上希望大小具有宽度/高度的比率,然后根据该比率“增长”以适合文本。我看过Graphics.MeasureString
,但我认为它没有做我正在寻找的东西(也许它确实如此,我只是错误地使用它。)
我不想指定要绘制的矩形的特定宽度。相反,我想说在给定最小宽度的情况下找到适合此文本的最小宽度/高度,但找到的矩形必须具有一定的宽度和高度比。
这不一定是C#特有的,解决这个问题的任何想法我都确定可以映射到C#。
谢谢!
答案 0 :(得分:1)
我相信你可以使用Graphics.MeasureString。这是我在GUI代码中用来在文本周围绘制矩形的内容。您将文本和要使用的字体交给它,它会返回一个矩形(技术上是一个SizeF
对象 - 宽度和高度)。然后你可以按你想要的比例调整这个矩形:
Graphics g = CreateGraphics();
String s = "Hello, World!";
SizeF sizeF = g.MeasureString(s, new Font("Arial", 8));
// Now I have a rectangle to adjust.
float myRatio = 2F;
SizeF adjustedSizeF = new SizeF(sizeF.Width * myRatio, sizeF.Height * myRatio);
RectangleF rectangle = new RectangleF(new PointF(0, 0), adjustedSizeF);
我能正确理解你的问题吗?
答案 1 :(得分:1)
您应该使用TextRenderer.MeasureText,所有控件都使用TextRenderer在.NET 2.0及更高版本中绘制文本。
您的问题没有明确的解决方案,有很多种方法可以在Rectangle中插入文本。一个只显示一行的宽行与一个显示多行的窄行一样有效。你必须约束其中一个维度。这是一个现实的要求,这个矩形显示在一些其他控件内,并且该控件具有某个ClientSize。你需要决定如何安排它。
答案 2 :(得分:0)
关于System.Windows.Forms.Label的评论背面,也许你可以看一下驱动Label绘画的代码?如果你使用Reflector,这应该让你成为一部分。
似乎有一些方法就像GetPreferredSizeCore()那样可能有你想要的东西,我肯定可以通过一点点的工作使其足够通用。
答案 3 :(得分:0)
我找到了自己的解决方案。以下代码确定最适合文本的矩形(匹配比率)。它使用分而治之来找到最接近的矩形(通过将某个“步长”减去宽度)。此算法使用始终满足的最小宽度,我确信可以将其修改为包含最大宽度。想法?
private Size GetPreferredSize(String text, Font font, StringFormat format)
{
Graphics graphics = this.CreateGraphics();
if (format == null)
{
format = new StringFormat();
}
SizeF textSize = SizeF.Empty;
// The minimum width allowed for the rectangle.
double minWidth = 100;
// The ratio for the height compared to the width.
double heightRatio = 0.61803399; // Gloden ratio to make it look pretty :)
// The amount to in/decrement for width.
double step = 100;
// The new width to be set.
double newWidth = minWidth;
// Find the largest width that the text fits into.
while (true)
{
textSize = graphics.MeasureString(text, font, (int)Math.Round(newWidth), format);
if (textSize.Height <= newWidth * heightRatio)
{
break;
}
newWidth += step;
}
step /= 2;
// Continuously divide the step to adjust the rectangle.
while (true)
{
// Ensure step.
if (step < 1)
{
break;
}
// Ensure minimum width.
if (newWidth - step < minWidth)
{
break;
}
// Try to subract the step from the width.
while (true)
{
// Measure the text.
textSize = graphics.MeasureString(text, font, (int)Math.Round(newWidth - step), format);
// If the text height is going to be less than the new height, decrease the new width.
// Otherwise, break to the next lowest step.
if (textSize.Height < (newWidth - step) * heightRatio)
{
newWidth -= step;
}
else
{
break;
}
}
step /= 2;
}
double width = newWidth;
double height = width * heightRatio;
return new Size((int)Math.Ceiling(width), (int)Math.Ceiling(height));
}