Domanda

Ho eseguito la sottoclasse di un controllo in C # WinForms e sono un testo di disegno personalizzato nel mio gestore OnPaint () . Il carattere è impostato su Courier New usando il seguente codice nel mio modulo:

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

Nel controllo stesso, la stringa è memorizzata in realText e utilizzo il seguente codice per disegnarla sullo schermo:

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

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

Il risultato per un testo di esempio casuale appare come segue: http://img219.imageshack.us/img219/1778/courier.png

Se ingrandisci, puoi vedere, ad esempio, che lo spazio tra il primo 'as' è diverso dallo spazio tra il secondo 'as' (1 pixel contro 2 pixel). Qualcuno ha idea di cosa potrebbe causare questo, o come posso impedirlo? C'è una stranezza molto più simile nella spaziatura mentre disegno con caratteri diversi, ma presumo siano tutti risultati dello stesso problema.

Grazie in anticipo per qualsiasi idea tu possa avere.

È stato utile?

Soluzione

Suppongo che sia perché stai usando Graphics.DrawString () anziché TextRenderer.DrawText () . Il primo dipinge il testo usando GDI + che è un po 'scadente e obsoleto. Quest'ultimo utilizza GDI, che è più moderno (in termini di rendering del testo). Credo che questa sia la differenza rilevata dalla risposta precedente (WinForms vs. Windows).

Potresti anche provare il sovraccarico di Graphics.DrawString () che accetta un StringFormat e specifica StringFormat.GenericTypographic . Tuttavia, questo è davvero un po 'un trucco intorno al problema. Se stai utilizzando .NET 2.0 o versioni successive, dovresti utilizzare la classe TextRenderer anziché la classe Graphics scadente per tutte le tue esigenze di rendering del testo. Graphics.MeasureString () e Graphics.DrawString () esistono rigorosamente per la retrocompatibilità con .NET 1.0 e 1.1.

modifica: Oh sì, e il tuo codice perde un oggetto GDI su ogni ciclo di pittura. Gli oggetti pennello sono wrapper gestiti attorno a risorse non gestite, pertanto devono essere esplicitamente eliminati.

Altri suggerimenti

Devo essere sincero, ma questo non mi è mai successo prima. Tuttavia, prova a impostare SmoothingMode su Antialiasing:

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

Un'altra cosa a parte, assicurati che il tuo utilizzo abbia DoubleBuffer impostato su true. Inoltre, cerca di non creare un nuovo SolidBrush in ogni chiamata OnPaint ..

La mia esperienza con la pittura del testo in controlli sottoclassati usando WinForms è che il motore di rendering del testo che usa (GDI +?) non è buono come il motore di font di Windows, e certamente dà risultati diversi anche quando funziona bene.

Sono l'autore di un componente aggiuntivo di Visual Studio ( http://entrian.com/source-search ) che deve dipingere i controlli all'interno di Visual Studio, e per rendere i caratteri simili ai controlli standard in Visual Studio (elenchi, treeview, ecc.) Devo bypassare WinForms e dipingere il testo 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);

... e famiglia.

Probabilmente non quello che volevi sentire, ma eccolo qui

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