Возможная ошибка с Graphics.DrawString и TextRenderingHint в.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) Если я установил explicity, то установил режим первого элемента управления в ClearTypeGridFit, который в моем случае совпадает со значением по умолчанию, это решает проблему.

(2) Если вы поместите третий элемент управления в форму и оставите в режиме по умолчанию, это решит проблему.

(3) TextRenderer.DrawText не повторяет проблему.

(4) Если я унаследую элемент управления меткой и переопределю метод onpaint, чтобы установить режим рендеринга, проблема не будет повторяться, даже если я установлю UseCompatibleTextRendering - что заставляет метку рендерить с DrawString вместо DrawText.

Я на XP с включенным cleartype и использую Visual Studio 2008 Express Edition.

ETA: я пробовал это в C# и происходит то же самое

3 ответа

Это похоже на проблему, с которой мы столкнулись раньше. В коде запуска вашего приложения есть вызов Application.SetCompatibleTextRenderingDefault(true)? (Или я могу забыть)

Если это так, переключите состояние этого bool, чтобы изменить режим рендеринга текста, и он должен работать как положено.

У меня была похожая проблема. Я назвал это:

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

Затем я попробовал то, что предложил Джуда Химанго, и все работало просто отлично.
Это выглядит определенно как ошибка для меня!

Так что просто позвоните:

    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)
{ .. }

каждый последующий вызов DrawString работает правильно с установкой TextRenderingHint или без нее.

Другие вопросы по тегам