在.Net Winforms中使用Graphics.DrawString和TextRenderingHint可能存在bug

3
这是一个控件的OnPaint方法,它继承自控件,并提供了一个属性来获取/设置文本呈现提示:
 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进行呈现。
我正在使用启用了ClearType的XP和Visual Studio 2008 Express版。
预计完成时间:我已经在C#中尝试过了,结果是相同的。
3个回答

1

这听起来像是我们之前遇到的问题。在您的应用程序启动代码中,是否有调用Application.SetCompatibleTextRenderingDefault(true)?(或者它可能被设置为false,我忘了)。

如果是这样,请切换该布尔值的状态以更改文本呈现模式,然后它应该按预期工作。


很遗憾,没有电话。虽然我自己绘制文本并明确使用gdi+ drawstring方法,但如果这解决了问题,我会感到惊讶。另外,根据我的观察2,似乎这是一个更深层次的问题。 - Jules
好的。也许还值得一试,将该调用添加到您的应用程序启动中。尝试使用SetCompatibleTextRenderingDefault(true)和SetCompatibleTextRenderingDefault(false),并查看它对您的应用程序产生的影响。虽然已经有一段时间了,但我似乎记得这甚至对DrawString等内容也有影响,因为我已经转向WPF很久了。 - Judah Gabriel Himango

0

我有一个类似的问题。我称之为:

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建议的方法,一切都正常工作了。
这对我来说绝对是一个bug!

所以请确保您调用:

    Application.SetCompatibleTextRenderingDefault(true);

对我很有用!


0

这个 bug 在 .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)
{ .. }

每次调用DrawString,无论是否在之前设置了TextRenderingHint,都能正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接