【问题标题】:Disable word breaking when wrapping lines in .NET DrawString在 .NET DrawString 中换行时禁用断字
【发布时间】:2010-03-23 10:29:05
【问题描述】:

我正在使用 .NET 将字符串绘制到有限的空间中。我希望字符串尽可能大。我将字符串分成更多行没有问题(如果它留在矩形内)。现在的问题是:我不希望 .NET 在单词中间将字符串分成不同的行。 例如,字符串“Test”以大字体打印在单行上。字符串“Testing”应该以较小的字体打印在单行上(而不是“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));
    }

【问题讨论】:

    标签: .net drawstring word-wrap


    【解决方案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");
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以根据字符串的长度/大小调整控件大小。这将确保字符串适合一行。

      【讨论】:

      • 但是我有一个固定的空间,我不想调整它的大小。我想缩小/换行文本以使其适合
      【解决方案3】:

      你所得到的似乎是正确的答案。我认为没有一个调用框架方法可以为您完成所有这些工作。如果您在 winform 中渲染按钮和文本的另一个选项,您应该查看 ButtonRenderer 和 TextRenderer 类。在调用 DrawText 或 MeasureString 时,您还可以指定 TextFormatFlags,这将允许您指定 WorkBreak、SingleLine 或使用 Ellipse 截断。

      【讨论】:

        猜你喜欢
        • 2011-02-28
        • 2011-05-04
        • 1970-01-01
        • 1970-01-01
        • 2012-11-15
        • 2011-11-27
        • 2017-04-27
        • 1970-01-01
        • 2015-01-02
        相关资源
        最近更新 更多