Проблема с CreateGraphics и рисованием строк - PullRequest
2 голосов
/ 15 января 2010

Элемент управления ниже рисует строку в прямоугольнике. При перемещении мыши выполняется проверка попадания в прямоугольник строки, и строка перерисовывается с помощью CreateGraphics. Раздражающая проблема заключается в том, что текст рисуется не так, как в обработчике Paint; кажется, что он смещен примерно на 1 пиксель, а эффект похож на жирный шрифт. Как создать графический объект точно так же, как в обработчике Paint, чтобы текст рисовался одинаково? Обычно вы бы аннулировали и перерисовывали все в событии Paint, но у меня есть потенциально сотни других элементов рисования, и я хочу нарисовать только строку. Должен ли я попытаться сделать какой-либо рисунок вне события Paint или это ошибка?

Пример управления:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Test.TestModes
{
    public partial class ExampleControl: UserControl
    {
        private const string testString = "0123456789";
        private RectangleF stringRect = new RectangleF(10, 10, 100, 20);

        public ExampleControl()
        {
            InitializeComponent();
        }

        private void ExampleControl_Paint(object sender, PaintEventArgs e)
        {
            Font font = new Font("Arial", 12, FontStyle.Regular);

            e.Graphics.DrawString(testString, font, Brushes.Black, stringRect);

            font.Dispose();
        }

        private void DrawString(bool hit)
        {
            Font font = new Font("Arial", 12, FontStyle.Regular);

            using(Graphics g = CreateGraphics())
            {
                g.SetClip(ClientRectangle);
                if(hit)
                    g.DrawString(testString, font, Brushes.Red, stringRect);
                else
                    g.DrawString(testString, font, Brushes.Black, stringRect);
            }

            font.Dispose();
        }

        private void ExampleControl_MouseMove(object sender, MouseEventArgs e)
        {
            if(stringRect.Contains(e.Location))
                DrawString(true);
            else
                DrawString(false);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Invalidate();
        }


    }
}

1 Ответ

8 голосов
/ 15 января 2010

Это вызов CreateGraphics (), который косвенно доставляет вам неприятности. Проблема заключается в сглаживании текста. Обычный цикл рисования стирает фон, прежде чем рисовать что-то сверху. Этого не происходит в вашем случае, вы рисуете текст поверх существующего текста. Побочным эффектом является то, что пиксели, используемые для создания псевдонимов, становятся темнее при каждом рисовании. Конечный результат выделяется жирным шрифтом и заметно зазубренными контурами текста.

Исправить несложно: начните с чистого листа, прежде чем рисовать:

    using (Graphics g = CreateGraphics()) {
        g.Clear(this.BackColor);                <=== added
        g.SetClip(ClientRectangle);
        // etc..
    }

Теперь вы также можете столкнуться с проблемой рисования, известной как «мерцание». Это может быть еще не так заметно, но это будет, когда вы будете больше рисовать. Мерцание подавляется двойной буферизацией. Функция, поддерживаемая Windows Forms, но только если вы используете стандартные методы рисования. Другими словами: нет CreateGraphics ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...