Domanda

Sto utilizzando .NETCF (Windows Mobile) Graphics classe e il DrawString() metodo per visualizzare un singolo carattere sullo schermo.

Il problema è che non riesco a centrarlo correttamente.Non importa cosa ho impostato per la coordinata Y della posizione del rendering della stringa, risulterà sempre inferiore a quella e maggiore è la dimensione del testo maggiore è l'offset Y.

Ad esempio, con la dimensione del testo 12, l'offset è di circa 4, ma con la dimensione 32 l'offset è di circa 10.

Voglio che il personaggio occupi verticalmente la maggior parte del rettangolo in cui viene disegnato e sia centrato orizzontalmente.Ecco il mio codice di base. this fa riferimento al controllo utente in cui viene disegnato.

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

Sì, so che c'è il controllo etichetta che potrei usare al suo posto e impostare la centratura con quello, ma in realtà devo farlo manualmente con il Graphics classe.

È stato utile?

Soluzione 3

Attraverso una combinazione dei suggerimenti che ho ricevuto, sono arrivato a questo:

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

Finora funziona perfettamente.

L'unica cosa che cambierei è spostare la chiamata FindBestFitFont() all'evento OnResize() in modo da non chiamarla ogni volta che disegno una lettera.Deve essere chiamato solo quando cambia la dimensione del controllo.L'ho semplicemente incluso nella funzione per completezza.

Altri suggerimenti

Vorrei aggiungere un altro voto per l'oggetto StringFormat.Puoi usarlo semplicemente per specificare "centro, centro" e il testo verrà disegnato centralmente nel rettangolo o nei punti forniti:

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

Tuttavia c'è un problema con questo in CF.Se usi Center per entrambi i valori, TextWrapping viene disattivato.Non ho idea del perché ciò accada, sembra essere un bug del CF.

Per allineare un testo utilizzare quanto segue:

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

Tieni presente che il testo qui è allineato entro i limiti indicati.In questo esempio si tratta di ClientRectangle.

Per disegnare un testo centrato:

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

Determinare la dimensione ottimale del carattere per riempire un'area è un po' più difficile.Un'anima funzionante che ho trovato è prova ed errore:inizia con un carattere grande, quindi misura ripetutamente la stringa e riduci il carattere finché non si adatta.

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

Lo useresti come:

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)

È possibile utilizzare un'istanza di StringFormat oggetto passato nel DrawString metodo per centrare il testo.

Vedere Metodo Graphics.DrawString E Classe StringFormat.

Ecco del codice.Ciò presuppone che tu lo stia facendo su un modulo o su 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));

Dal tuo post, sembra che la parte ClientRectangle (come in, non la stai utilizzando) sia ciò che ti dà difficoltà.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top