2008-08-11 10 views
38

Ich verwende die .NETCF (Windows Mobile) Graphics Klasse und die DrawString() Methode, um ein einzelnes Zeichen auf dem Bildschirm zu rendern.Zentrale Textausgabe von Graphics.DrawString()

Das Problem ist, dass ich nicht scheinen kann, um es richtig zentriert zu bekommen. Egal, was ich für die Y-Koordinate der Position des String-Renderings eingestellt habe, es kommt immer niedriger heraus und je größer die Textgröße, desto größer ist der Y-Offset.

Zum Beispiel bei Textgröße 12, ist der Versatz etwa 4, aber bei 32 der Versatz etwa 10

ich den Charakter wollen vertikal meisten des Rechtecks ​​nehmen sie eingezogen Sein und zentriert werden horizontal. Hier ist mein grundlegender Code. this verweisen auf die Benutzersteuerung in gezeichnet werden wird.

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

Ja, ich weiß, dass es das Label-Steuerelement ist, dass ich stattdessen verwenden könnte und die Zentrierung mit diesem Satz, aber ich brauche eigentlich dies mit der manuell zu tun Graphics Klasse.

Antwort

13

Durch eine Kombination der Vorschläge, die ich bekam, kam ich mit auf den Punkt:

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

Bisher funktioniert das einwandfrei.

Die einzige Sache, die ich ändern würde, ist, den Aufruf FindBestFitFont() zum Ereignis OnResize() zu verschieben, so dass ich es nicht jedes Mal anrufe, wenn ich einen Brief zeichne. Es muss nur aufgerufen werden, wenn sich die Kontrollgröße ändert. Ich habe es nur in die Funktion zur Vollständigkeit aufgenommen.

1

Hier ist ein Code. Dies setzt voraus, dass Sie dies in einem Formular oder einem Benutzersteuerelement tun.

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

Von Ihrem Beitrag, es klingt wie der ClientRectangle Teil (wie in, Sie verwenden es nicht) ist das, was man Schwierigkeiten hat zu geben.

8

einen zentrierten Text zu zeichnen:

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

Bestimmen der optimalen Schriftgröße eine Fläche zu füllen ein bisschen schwieriger ist. Eine funktionierende Lösung, die ich gefunden habe, ist Trial-and-Error: Beginnen Sie mit einer großen Schriftart, messen Sie dann die Zeichenfolge wiederholt und verkleinern Sie die Schriftart, bis sie passt.

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

du so verwenden würde:

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

danke für das Zeigen der anderen Möglichkeit, Sachen zu zeichnen, es hilft mir wirklich mit einem Zentrum Ausrichtung Problem stellt sich heraus, TextRenderer.DrawText ist genauer als eine einfache e.graphics.drawstring vielen Dank, vote up von mir :) –

54

Ich möchte eine weitere Abstimmung für das StringFormat-Objekt hinzufügen. Sie können dies einfach verwenden, um anzugeben „Zentrum, Zentrum“ und der Text wird zentral im Rechteck oder Punkte vorgesehen gezogen werden:

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

Allerdings gibt dabei ist, ein Problem in CF. Wenn Sie Center für beide Werte verwenden, wird TextWrapping deaktiviert.Keine Ahnung, warum das passiert, es scheint ein Bug mit dem CF zu sein.

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

Bitte beachten Sie, dass die hier Text in den angegebenen Grenzen ausgerichtet ist:

40

Um einen Text verwenden Sie die folgende auszurichten. In diesem Beispiel ist dies der ClientRectangle.

+0

Chris Lösung ist großartig. BTW, wenn Sie in der Mitte der horizontalen, aber vertikal an einer beliebigen Position setzen möchten: e.Graphics.DrawString ("Meine Zeichenfolge", this.Font, Brushes.Black, e.CellBounds.Width/2, y, sf); // y ist die vertikale Position – camino

Verwandte Themen