2008-08-11 22 views
38

Estoy usando la clase .NETCF (Windows Mobile) Graphics y el método DrawString() para representar un solo carácter en la pantalla.Salida de texto del centro de Graphics.DrawString()

El problema es que parece que no puedo centrarlo correctamente. No importa lo que establezca para la coordenada Y de la ubicación del procesamiento de cadenas, siempre sale más bajo que eso y cuanto mayor es el tamaño del texto, mayor es el desplazamiento en Y.

Por ejemplo, en el tamaño del texto 12, el desplazamiento es aproximadamente 4, pero a los 32 años el desplazamiento es de aproximadamente 10.

Quiero que el carácter para tomar verticalmente la mayor parte del rectángulo que está siendo aspirado y se centra horizontalmente. Aquí está mi código básico. this hace referencia al control de usuario que está siendo aspirado.

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í, ya sé que es el control de etiqueta que podría utilizar en su lugar y establecer el centrado con eso, pero en realidad es necesario para hacer esto manualmente con el Graphics clase.

Respuesta

13

A través de una combinación de las sugerencias que tengo, se me ocurrió esto:

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

Hasta ahora, esto funciona a la perfección.

Lo único que cambiaría es mover la llamada FindBestFitFont() al evento OnResize() para que no lo llame cada vez que dibujo una letra. Solo necesita ser llamado cuando el tamaño de control cambia. Lo acabo de incluir en la función de completitud.

1

Aquí hay algunos códigos. Esto supone que está haciendo esto en un formulario, o 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)); 

Desde su puesto, parece que la parte ClientRectangle (como en, que no se esté utilizando) es lo que te está dando problemas.

8

Para dibujar un texto centrado:

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

Determinación del tamaño de fuente óptima para rellenar un área es un poco más difícil. Una alma ingeniosa que encontré es prueba y error: comience con una letra grande, luego mida repetidamente la cadena y reduzca la fuente hasta que encaje.

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

que tendría que utilizar esto como:

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

gracias por mostrar la otra forma de dibujar cosas realmente me ayuda con un problema de alineación del centro resulta TextRenderer.DrawText es más preciso que un simple e.graphics.drawstring muchas gracias, vota por mí :) –

54

Me gustaría agregar otra votación para el objeto StringFormat. Puede utilizar esto simplemente para especificar "centro, centro" y el texto se dibujará en el centro del rectángulo o puntos siempre y cuando:

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

Sin embargo hay un problema con esto en la FQ Si usa Center para ambos valores, desactiva Text Wrapping.No tengo idea de por qué sucede esto, parece ser un error con el CF.

40

Para alinear un texto utilice la siguiente:

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

Tenga en cuenta que el texto que aquí se alinea en los límites dados. En esta muestra, este es el rectángulo de cliente.

+0

Chris's la solución es genial Por cierto, si desea establecer en el centro de la horizontal, pero vertical en cualquier posición: e.Graphics.DrawString ("Mi cadena", this.Font, Brushes.Black, e.CellBounds.Width/2, y, sf); // y es posición vertical – camino

Cuestiones relacionadas