2008-08-11 3 views
38

J'utilise la classe .NETCF (Windows Mobile) Graphics et la méthode DrawString() pour afficher un seul caractère à l'écran.Sortie du texte central de Graphics.DrawString()

Le problème est que je n'arrive pas à le centrer correctement. Peu importe ce que je définis pour la coordonnée Y de l'emplacement de la chaîne de rendu, elle sort toujours plus bas que cela et plus la taille du texte est grande, plus le décalage Y est important.

Pour est environ 4 exemple, à la taille du texte 12, le décalage, mais à 32 le décalage est d'environ 10.

Je veux que le personnage de prendre verticalement vers le haut la plupart du rectangle, il est en cours d'élaboration et centrée horizontalement. Voici mon code de base. this référence le contrôle de l'utilisateur, il est en cours d'élaboration dans.

Graphics g = this.CreateGraphics(); 

float padx = ((float)this.Size.Width) * (0.05F); 
float pady = ((float)this.Size.Height) * (0.05F); 

float width = ((float)this.Size.Width) - 2 * padx; 
float height = ((float)this.Size.Height) - 2 * pady; 

float emSize = height; 

g.DrawString(letter, new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular), 
      new SolidBrush(Color.Black), padx, pady); 

Oui, je sais qu'il est le contrôle de l'étiquette que je pouvais utiliser la place et régler le centrage avec cela, mais je ne réellement besoin de le faire manuellement avec le Graphics classe.

Répondre

13

Grâce à une combinaison des suggestions que j'ai, je suis venu avec ceci:

private void DrawLetter() 
    { 
     Graphics g = this.CreateGraphics(); 

     float width = ((float)this.ClientRectangle.Width); 
     float height = ((float)this.ClientRectangle.Width); 

     float emSize = height; 

     Font font = new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular); 

     font = FindBestFitFont(g, letter.ToString(), font, this.ClientRectangle.Size); 

     SizeF size = g.MeasureString(letter.ToString(), font); 
     g.DrawString(letter, font, new SolidBrush(Color.Black), (width-size.Width)/2, 0); 

    } 

    private Font FindBestFitFont(Graphics g, String text, Font font, Size proposedSize) 
    { 
     // Compute actual size, shrink if needed 
     while (true) 
     { 
      SizeF size = g.MeasureString(text, font); 

      // It fits, back out 
      if (size.Height <= proposedSize.Height && 
       size.Width <= proposedSize.Width) { return font; } 

      // Try a smaller font (90% of old size) 
      Font oldFont = font; 
      font = new Font(font.Name, (float)(font.Size * .9), font.Style); 
      oldFont.Dispose(); 
     } 
    } 

Jusqu'à présent, cela fonctionne parfaitement. La seule chose que je voudrais changer est de déplacer l'appel FindBestFitFont() à l'événement OnResize() afin que je ne l'appelle pas chaque fois que je dessine une lettre. Il n'a besoin d'être appelé que lorsque la taille du contrôle change. Je l'ai juste inclus dans la fonction pour l'exhaustivité.

1

Voici du code. Cela suppose que vous le faites sur un formulaire ou un UserControl.

Graphics g = this.CreateGraphics(); 
SizeF size = g.MeasureString("string to measure"); 

int nLeft = Convert.ToInt32((this.ClientRectangle.Width/2) - (size.Width/2)); 
int nTop = Convert.ToInt32((this.ClientRectangle.Height/2) - (size.Height/2)); 

À partir de votre poste, cela ressemble à la partie ClientRectangle (comme, vous ne l'utilisez pas) est ce qui vous donne du mal.

8

Pour dessiner un texte centré:

TextRenderer.DrawText(g, "my text", Font, Bounds, ForeColor, BackColor, 
    TextFormatFlags.HorizontalCenter | 
    TextFormatFlags.VerticalCenter | 
    TextFormatFlags.GlyphOverhangPadding); 

Détermination de la taille de la police optimale pour remplir une zone est un peu plus difficile. Une des méthodes de travail que j'ai trouvées est celle du tâtonnement: commencez avec une grande police, puis mesurez la chaîne à plusieurs reprises et réduisez la police jusqu'à ce qu'elle soit ajustée.

Font FindBestFitFont(Graphics g, String text, Font font, 
    Size proposedSize, TextFormatFlags flags) 
{ 
    // Compute actual size, shrink if needed 
    while (true) 
    { 
    Size size = TextRenderer.MeasureText(g, text, font, proposedSize, flags); 

    // It fits, back out 
    if (size.Height <= proposedSize.Height && 
     size.Width <= proposedSize.Width) { return font; } 

    // Try a smaller font (90% of old size) 
    Font oldFont = font; 
    font = new Font(font.FontFamily, (float)(font.Size * .9)); 
    oldFont.Dispose(); 
    } 
} 

Vous souhaitez l'utiliser comme:

Font bestFitFont = FindBestFitFont(g, text, someBigFont, sizeToFitIn, flags); 
// Then do your drawing using the bestFitFont 
// Don't forget to dispose the font (if/when needed) 
+0

merci de montrer l'autre façon de dessiner des choses cela m'aide vraiment avec un problème d'alignement de centre s'avère TextRenderer.DrawText est plus précis qu'un simple e.graphics.drawstring merci beaucoup, éloignez-vous de moi :) –

54

Je voudrais ajouter un autre vote pour l'objet StringFormat. Vous pouvez utiliser cela simplement pour spécifier « centre, centre » et le texte sera établi au centre du rectangle ou des points fournis: Cependant

StringFormat format = new StringFormat(); 
format.LineAlignment = StringAlignment.Center; 
format.Alignment = StringAlignment.Center; 

il y a un problème avec cela dans CF. Si vous utilisez Center pour les deux valeurs, il désactive TextWrapping.Aucune idée pourquoi cela se produit, il semble être un bug avec les FC.

40

Pour aligner un texte utilisez ce qui suit:

StringFormat sf = new StringFormat(); 
sf.LineAlignment = StringAlignment.Center; 
sf.Alignment = StringAlignment.Center; 
e.Graphics.DrawString("My String", this.Font, Brushes.Black, ClientRectangle, sf); 

S'il vous plaît noter que le texte est aligné ici dans les limites données. Dans cet exemple, c'est le ClientRectangle.

+0

Chris's la solution est géniale. BTW si vous voulez définir au centre de l'horizontale, mais verticale à n'importe quelle position: e.Graphics.DrawString ("Ma chaîne", this.Font, Brushes.Black, e.CellBounds.Width/2, y, sf); // y est la position verticale – camino

Questions connexes