Pregunta

He subclasificado un control en C # WinForms, y soy un texto de dibujo personalizado en mi controlador OnPaint () . La fuente se establece en Courier New usando el siguiente código en mi formulario:

FontFamily family = new FontFamily("Courier New");
this.myControl.Font = new Font(family, 10);

En el control en sí, la cadena se almacena en realText , y utilizo el siguiente código para dibujarlo en la pantalla:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);

    e.Graphics.DrawString(realText, Font, new SolidBrush(ForeColor), ClientRectangle);
}

El resultado para un texto de ejemplo aleatorio tiene el siguiente aspecto: http://img219.imageshack.us/img219/1778/courier.png

Si hace zoom, puede ver, por ejemplo, que el espacio entre el primer 'as' es diferente al espacio entre el segundo 'as' (1 píxeles versus 2 píxeles). ¿Alguien tiene alguna idea de lo que podría estar causando esto o cómo puedo evitar que ocurra? Hay muchas más rarezas similares en el espaciado cuando dibujo con diferentes tipos de letra, pero supongo que todos son resultados del mismo problema.

Gracias de antemano por cualquier idea que pueda tener.

¿Fue útil?

Solución

Supongo que es porque estás usando Graphics.DrawString () en lugar de TextRenderer.DrawText () . El primero pinta el texto usando GDI +, que es un poco desagradable y anticuado. Este último usa GDI, que es más moderno (en términos de representación de texto). Creo que esta es la diferencia observada en la respuesta anterior (WinForms vs. Windows).

También puede intentar la sobrecarga de Graphics.DrawString () que requiere un StringFormat y especifique StringFormat.GenericTypographic . Sin embargo, esto es realmente un truco para solucionar el problema. Si está utilizando .NET 2.0 o posterior, debe usar la clase TextRenderer en lugar de la clase de Graphics para todas sus necesidades de representación de texto. Graphics.MeasureString () y Graphics.DrawString () existen estrictamente para la compatibilidad con versiones anteriores de .NET 1.0 y 1.1.

editar: Ah, sí, y su código pierde un objeto GDI en cada ciclo de pintura. Los objetos de pincel son contenedores administrados alrededor de recursos no administrados, por lo que deben eliminarse explícitamente.

Otros consejos

Tengo que ser honesto, pero esto nunca me había pasado antes. Sin embargo, intente configurar el SmoothingMode en Antialiasing:

e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

Otra cosa aparte, asegúrese de que el uso de DoubleBuffer esté establecido en verdadero. Además, trate de no crear un nuevo SolidBrush en cada llamada de OnPaint ...

Mi experiencia con la pintura de texto en controles subclasificados usando WinForms es que el motor de representación de texto que usa (GDI +?) no es tan bueno como el propio motor de fuentes de Windows, y ciertamente da resultados diferentes incluso cuando funciona bien.

Soy el autor de un complemento de Visual Studio ( http://entrian.com/source-search ) que necesita pintar controles dentro de Visual Studio, y para que las fuentes tengan el mismo aspecto que los controles estándar en Visual Studio (vistas de lista, vistas de árbol, etc.) tengo que omitir WinForms y pintar el texto usando Win32 API:

[DllImport("gdi32.dll")]
public static extern bool ExtTextOut(IntPtr hdc, int X, int Y,
   uint fuOptions, [In] ref RECT lprc, string lpString, uint cbCount,
   [In] int[] lpDx);

... y familia.

Probablemente no sea lo que querías escuchar, pero ahí está.

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