vertical tutorial c# graphics compact-framework

c# - tutorial - Salida de texto central desde Graphics.DrawString()



c# drawstring vertical text (6)

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

El problema es que parece que no puedo centrarme correctamente. Independientemente de 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 de texto 12, el desplazamiento es aproximadamente 4, pero a 32 el desplazamiento es aproximadamente 10.

Quiero que el personaje tome verticalmente la mayor parte del rectángulo en el que se está dibujando y se centre horizontalmente. Aquí está mi código básico. this hace referencia al control de usuario en el que se está dibujando.

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í, sé que existe el control de etiqueta que podría usar en su lugar y establecer el centrado con eso, pero en realidad necesito hacerlo manualmente con la clase Graphics .


A través de una combinación de las sugerencias que obtuve, 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.


Aquí hay un código. 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 publicación, parece que la parte de ClientRectangle (como, por ejemplo, no la está usando) es lo que le está dando dificultades.


Para dibujar un texto centrado:

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

Determinar el tamaño de fuente óptimo para llenar 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(); } }

Lo usarías 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)


Para alinear un texto, use lo 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 aquí está alineado en los límites dados. En esta muestra, este es el rectángulo de cliente.



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

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

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