Проблема с CreateGraphics и рисованием строк

2

Нижеприведенный элемент рисует строку в прямоугольнике. При перемещении мыши в прямоугольнике строк есть тест на удар, а строка перерисовывается через 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
    Почему вы используете CreateGraphics в любом случае? Сделайте всю свою живопись внутри события Боли, вот для чего оно здесь.
  • 0
    Как бы вы нарисовали только строку, а не остальные элементы управления?
Показать ещё 3 комментария
Теги:
winforms

1 ответ

7
Лучший ответ

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

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

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

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

  • 0
    Отлично, вот и все. Однако, когда я делаю это, я теряю эффект DoubleBuffered и мерцаю при перемещении мыши. (Я добавил DoubleBuffered = true в событии загрузки). Так что, думаю, я никогда не смогу рисовать за пределами события Paint.
  • 3
    Ну, вы можете сделать двойной буфер самостоятельно. Используйте Bitmap, Graphics.FromImage () и рисуйте в этом графическом контексте. Затем DrawImage () результат. Тем не менее, лучше просто вызывать Invalidate (), чтобы обработчик событий обычного Paint () рисовал.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню