我使用.NET将字符串绘制到有限的空间中。我希望字符串尽可能大。我没有问题,字符串分成更多的行(如果它停留在矩形内)。现在的问题是:我不希望.NET在一个单词的中间区分不同行中的字符串。 例如,字符串“Test”以大字体打印在单行上。字符串“测试”应该以较小的字体打印在单行上(而不是一行上的“Testi”和另一行上的“ng”),字符串“Test Test”应该以相当大的字体打印在两行上。
有人对如何限制.NET不打破我的话有想法吗?
我目前正在使用这样的代码:
internal static void PaintString(string s, int x, int y, int height, int maxwidth, Graphics g, bool underline)
{
FontStyle fs = FontStyle.Bold;
if (underline)
fs |= FontStyle.Underline;
Font fnt = new System.Drawing.Font("Arial", 18, fs);
SizeF size = g.MeasureString(s, fnt, maxwidth);
while (size.Height > height)
{
fnt = new System.Drawing.Font("Arial", fnt.Size - 1, fs);
size = g.MeasureString(s, fnt, maxwidth);
}
y = (int)(y + height / 2 - size.Height / 2);
g.DrawString(s, fnt, new SolidBrush(Color.Black), new Rectangle(x, y, maxwidth, height));
}
答案 0 :(得分:1)
找到字符串中最长的单词并使用MeasureString
确保它适合一行:
internal static void PaintString(string s, int x, int y, int maxHeight, int maxWidth, Graphics graphics, bool underline)
{
FontStyle fontStyle = FontStyle.Bold;
if (underline)
{
fontStyle |= FontStyle.Underline;
}
var longestWord = Regex.Split(s, @"\s+").OrderByDescending(w => w.Length).First();
using (var arial = new FontFamily("Arial"))
using (var format = new StringFormat(StringFormatFlags.LineLimit)) // count only lines that fit fully
{
int fontSize = 18;
while (fontSize > 0)
{
var boundingBox = new RectangleF(x, y, maxWidth, maxHeight);
using (var font = new Font(arial, fontSize, fontStyle))
{
int charactersFittedAll, linesFilledAll, charactersFittedLongestWord, linesFilledLongestWord;
graphics.MeasureString(s, font, boundingBox.Size, format, out charactersFittedAll, out linesFilledAll);
graphics.MeasureString(longestWord, font, boundingBox.Size, format, out charactersFittedLongestWord, out linesFilledLongestWord);
// all the characters must fit in the bounding box, and the longest word must fit on a single line
if (charactersFittedAll == s.Length && linesFilledLongestWord == 1)
{
Console.WriteLine(fontSize);
graphics.DrawString(s, font, new SolidBrush(Color.Black), boundingBox, format);
return;
}
}
fontSize--;
}
throw new InvalidOperationException("Use fewer and/or shorter words");
}
}
答案 1 :(得分:0)
您可以根据字符串的长度/大小调整控件大小。这将确保字符串适合一行。
答案 2 :(得分:0)
你所得到的似乎是正确的答案。我不认为只有一个调用框架方法可以为你做所有这些。如果您在winform中重新显示按钮和文本,则应该查看ButtonRenderer和TextRenderer类。调用DrawText或MeasureString时,您还可以指定TextFormatFlags,它允许您指定WorkBreak,SingleLine或使用Ellipse截断。