Frage

Ich verwende .NETCF (Windows Mobile) Graphics Klasse und die DrawString() Methode zum Rendern eines einzelnen Zeichens auf dem Bildschirm.

Das Problem ist, dass ich es scheinbar nicht richtig zentrieren kann.Unabhängig davon, was ich für die Y-Koordinate der Position des String-Renderings einstelle, liegt sie immer unter diesem Wert, und je größer die Textgröße, desto größer der Y-Versatz.

Bei der Textgröße 12 beträgt der Versatz beispielsweise etwa 4, bei 32 beträgt der Versatz jedoch etwa 10.

Ich möchte, dass das Zeichen vertikal den größten Teil des Rechtecks ​​einnimmt, in das es gezeichnet wird, und horizontal zentriert ist.Hier ist mein Basiscode. this verweist auf das Benutzersteuerelement, in das es gezeichnet 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 stattdessen die Beschriftungssteuerung gibt, die ich verwenden und damit die Zentrierung festlegen könnte, aber ich muss dies tatsächlich manuell mit der tun Graphics Klasse.

War es hilfreich?

Lösung 3

Durch die Kombination der Vorschläge, die ich bekommen habe, bin ich auf Folgendes gekommen:

    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.

Das Einzige, was ich ändern würde, wäre, den FindBestFitFont()-Aufruf auf das OnResize()-Ereignis zu verschieben, damit ich es nicht jedes Mal aufrufe, wenn ich einen Buchstaben zeichne.Es muss nur aufgerufen werden, wenn sich die Steuerelementgröße ändert.Der Vollständigkeit halber habe ich es nur in die Funktion aufgenommen.

Andere Tipps

Ich möchte eine weitere Stimme für das StringFormat-Objekt hinzufügen.Hiermit können Sie einfach „Mitte, Mitte“ angeben und der Text wird mittig im Rechteck oder an den dafür vorgesehenen Punkten gezeichnet:

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

Bei CF gibt es dabei jedoch ein Problem.Wenn Sie Center für beide Werte verwenden, wird TextWrapping deaktiviert.Keine Ahnung, warum das passiert, es scheint ein Fehler in der CF zu sein.

Um einen Text auszurichten, verwenden Sie Folgendes:

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 der Text hier in den vorgegebenen Grenzen ausgerichtet ist.In diesem Beispiel ist dies das ClientRectangle.

So zeichnen Sie einen zentrierten Text:

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

Etwas schwieriger ist es, die optimale Schriftgröße zum Ausfüllen eines Bereichs zu bestimmen.Eine funktionierende Lösung, die ich gefunden habe, ist Versuch und Irrtum:Beginnen Sie mit einer großen Schriftart, messen Sie dann wiederholt die Zeichenfolge 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();
  }
}

Sie würden dies verwenden als:

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)

Sie können eine Instanz von verwenden StringFormat Objekt in die übergeben DrawString Methode zum Zentrieren des Textes.

Sehen Graphics.DrawString-Methode Und StringFormat-Klasse.

Hier ist ein Code.Dies setzt voraus, dass Sie dies in einem Formular oder einem UserControl 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));

Aus Ihrem Beitrag geht hervor, dass der ClientRectangle-Teil (d. h. Sie verwenden ihn nicht) Ihnen Schwierigkeiten bereitet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top