Disable word breaking when wrapping lines in .NET DrawString

左心房为你撑大大i 提交于 2019-12-07 12:19:37

问题


I am using .NET to draw a string into a limited space. I want the string to be as big as possible. I have no problem in the string breaking up into more lines (if it stays inside the rectangle). Now the problem: I don't want .NET to break the string in different lines in the middle of a word. For example string "Test" prints on a single line in a big font. String "Testing" should print on a single line in a smaller font (and not "Testi" on one line and "ng" on another) and string "Test Test" should print on two lines in a fairly large font.

Anybody got ideas on how to restrict .NET not to break my words?

I'm currently using a code like this:

        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));
    }

回答1:


Find the longest word in your string and use MeasureString to ensure it fits on one line:

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:


You could resize the control size depending upon the length/size of the string. This would make sure that the string fits in one line.




回答3:


What you have got there seems to be the right answer. I dont think there is a single call to the framework method that can do all that for you. Another option if you are rending button and text in winform, you should look at the ButtonRenderer and TextRenderer class. When calling DrawText or MeasureString you can also specify TextFormatFlags which will allow you to specify WorkBreak, SingleLine or using Ellipse truncation.



来源:https://stackoverflow.com/questions/2499067/disable-word-breaking-when-wrapping-lines-in-net-drawstring

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!