2010-03-23 4 views
3

Я использую .NET для рисования строки в ограниченном пространстве. Я хочу, чтобы строка была как можно больше. У меня нет проблем в том, что строка разбивается на несколько строк (если она остается внутри прямоугольника). Теперь проблема: я не хочу, чтобы .NET разбивала строку на разные строки в середине слова. Например, строка «Тест» печатает на одной строке в большом шрифте. Строка «Тестирование» должна печатать на одной строке меньшим шрифтом (а не «Testi» в одной строке и «ng» на другой), а строка «Test Test» должна печатать на двух строках довольно крупным шрифтом.Отключить разрыв слова при обертке строк в .NET DrawString

У кого-нибудь появились идеи о том, как ограничить .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

Но у меня есть фиксированное пространство, которое я не хочу, чтобы изменить размер. Я хочу масштабировать/обертывать текст так, чтобы он соответствовал – JanHudecek

0

То, что у вас есть, кажется правильным ответом. Я не думаю, что есть один вызов метода framework, который может сделать все это для вас. Другой вариант, если вы разрываете кнопку и текст в winform, вы должны посмотреть на класс ButtonRenderer и TextRenderer. При вызове DrawText или MeasureString вы также можете указать TextFormatFlags, который позволит вам указать WorkBreak, SingleLine или использовать усечение эллипса.

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