簡體   English   中英

.Net Winforms 中的 Graphics.DrawString 和 TextRenderingHint 可能存在錯誤

[英]Possible bug with Graphics.DrawString and TextRenderingHint in .Net Winforms

這是一個控件的 OnPaint 方法,它簡單地從控件繼承並提供一個屬性來獲取/設置 textrenderinghint:

 Private _mode as TextRenderingHint = SystemDefault.
 Public Property Mode as TextRenderingHint
    Get & Set _mode
 ...

 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    Dim g = e.Graphics
    Dim savMode = g.Save
    g.TextRenderingHint = Me._mode
    g.DrawString(Me.Text, Me.Font, Brushes.Black, 0, 0)
    g.Restore(savMode)
    MyBase.OnPaint(e)
 End Sub

現在,如果您將其中兩個放置在表單上,​​將第一個保留為默認值並將第二個更改為 AntiAlias,它在設計時看起來不錯,但是當您運行應用程序時,第一個標簽的呈現模式已更改。 就好像 DrawString 方法改變了系統默認值一樣。

這里有一些觀察:

(1) 如果我明確地將第一個控件的模式設置為 ClearTypeGridFit,這與我的默認設置相同,它可以解決問題。

(2) 如果您在窗體上放置第三個控件並保留默認模式,則可以解決問題。

(3) TextRenderer.DrawText 沒有復制問題。

(4) 如果我繼承標簽控件並重寫 onpaint 方法來設置渲染模式,即使我設置了 UseCompatibleTextRendering 也不會復制問題 - 這會強制標簽使用 DrawString 而不是 DrawText 渲染。

我在 XP 上啟用了 cleartype 並使用了 Visual Studio 2008 Express Edition。

ETA:我在 C# 中嘗試過,同樣的事情發生了

這聽起來像我們之前遇到的問題。 在您的應用啟動代碼中,是否調用了 Application.SetCompatibleTextRenderingDefault(true)? (或者它可能被設置為假,我忘了)。

如果是這樣,請切換該布爾的狀態以更改文本呈現模式,它應該可以按預期工作。

這個錯誤似乎仍然存在於 .Net Framework 4.8 中。 我發現它可以解決,當應用程序啟動后第一次調用 DrawString() 時使用 SystemDefault-TextRenderingHint 完成:

using (Bitmap bmp = new Bitmap(1, 1))
using (Graphics gfx = Graphics.FromImage(bmp))
{
    // gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;    // bug
    gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;   // no bug
    gfx.DrawString("x", SystemFonts.DefaultFont, Brushes.Black, 0, 0);
}

所以如果這是一次完成

[STAThread]
static void Main(string[] args)
{ .. }

無論之前是否設置了 TextRenderingHint,對 DrawString 的每個后續調用都可以正常工作。

我有一個類似的問題。 我這樣稱呼:

Image i = new Bitmap(size, size);
Graphics g = Graphics.FromImage(i);

// When this line is uncommented TextRenderingHint is broken for ALL other Graphics-Objects.
// Setting "g.TextRenderingHint" later works sometimes in unpredictable ways.
//g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
...

我的啟動代碼如下所示:

[STAThread]
static void Main(string[] args)
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

然后我嘗試了 Judah Himango 的建議,一切正常。
這對我來說絕對是一個錯誤!

所以只要確保你打電話:

    Application.SetCompatibleTextRenderingDefault(true);

為我工作!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM