Pregunta

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

El problema es que me parece que no puede conseguir es centrado correctamente.No importa lo que me puse para la coordenada Y de la ubicación de la cadena de procesamiento, que siempre es menor que y mayor será el tamaño del texto la mayor Y offset.

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

Quiero que el personaje verticalmente ocupan la mayor parte del rectángulo es atraído y estar centrado horizontalmente.Aquí está mi código básico. this se hace referencia al control de usuario es atraído.

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

¿Fue útil?

Solución 3

A través de una combinación de las sugerencias que yo 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, este funciona a la perfección.

La única cosa que me gustaría cambiar es mover el FindBestFitFont() llamada a la OnResize() el evento así que no estoy llamando cada vez que me dibuje una carta.Sólo se necesita ser llamado cuando el tamaño de control de cambios.Me acaba de incluir en la función de integridad.

Otros consejos

Me gustaría añadir otro voto para el objeto StringFormat.Usted puede usar simplemente para especificar el "centro del centro" y el texto se dibuja de forma centralizada en el rectángulo o puntos que se señalan:

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

Sin embargo, hay un problema con esto en CF.Si utiliza el Centro de ambos valores, luego se pone TextWrapping off.Ni idea de por qué sucede esto, parece ser un bug con el CF.

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

Por favor, tenga en cuenta que el texto que aquí se alinean en los límites fijados.En este ejemplo de esto es el ClientRectangle.

Para dibujar un texto centrado:

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

Determinar el óptimo tamaño de fuente para rellenar un área es un poco más difícil.Un trabajo soultion he encontrado es el de ensayo-y-error:empezar con una gran fuente, entonces repetidamente medida de la cadena y reducir la fuente hasta que se ajuste.

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

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)

Puede utilizar una instancia de la StringFormat objeto pasado en la DrawString método para centrar el texto.

Ver Gráficos.El Método DrawString y StringFormat Clase.

Aquí un poco de código.Esto asume que usted está haciendo esto en un formulario o en un control de usuario.

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

De tu post, suena como el ClientRectangle parte (como en, usted no está en uso) es lo que está dando de dificultad.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top