2010-03-23 15 views
3

J'utilise .NET pour dessiner une chaîne dans un espace limité. Je veux que la corde soit aussi grande que possible. Je n'ai aucun problème dans la chaîne qui se brise en plusieurs lignes (si elle reste à l'intérieur du rectangle). Maintenant, le problème: je ne veux pas. NET pour casser la chaîne dans différentes lignes au milieu d'un mot. Par exemple, la chaîne "Test" imprime sur une seule ligne dans une grande police. La chaîne "Testing" devrait imprimer sur une seule ligne dans une police plus petite (et non "Testi" sur une ligne et "ng" sur une autre) et la chaîne "Test Test" devrait imprimer sur deux lignes dans une police assez grande.Désactiver la rupture de mot lors de l'encapsulation de lignes dans .NET DrawString

Quelqu'un a eu des idées sur la façon de restreindre .NET pour ne pas casser mes mots?

Je suis actuellement en utilisant un code comme ceci:

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

Répondre

0

Vous pouvez redimensionner la taille de commande en fonction de la longueur/taille de la chaîne. Cela permettrait de s'assurer que la chaîne s'inscrit dans une ligne.

+1

Mais j'ai un espace fixe que je ne veux pas redimensionner. Je veux réduire/encapsuler le texte pour qu'il corresponde – JanHudecek

0

Ce que vous avez là semble être la bonne réponse. Je ne pense pas qu'il existe un seul appel à la méthode du framework qui peut tout faire pour vous. Une autre option si vous déchirez le bouton et le texte en winform, vous devriez regarder la classe ButtonRenderer et TextRenderer. Lorsque vous appelez DrawText ou MeasureString, vous pouvez également spécifier TextFormatFlags qui vous permettra de spécifier WorkBreak, SingleLine ou d'utiliser la troncature Ellipse.

1

Trouver le plus long mot dans votre chaîne et utilisez MeasureString pour s'assurer qu'il tient sur une ligne:

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