Графика над картинкой не отображается, и если она есть, они мерцают перед исчезновением
Я работаю над приложением Windows Form и когда я использую System.Drawing.Graphics
в верхней части графического окна графика либо не появляется, либо появляется только на мгновение перед тем, как исчезнуть.
Это код, который я использую для установки картинки (это упрощенная версия и все еще демонстрирует поведение)
private void showGraphic()
{
pictureBox1.Invalidate();
System.Drawing.Graphics graphics = this.pictureBox1.CreateGraphics();
SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(128, 0, 0, 255));
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(100,100, 50, 50);
graphics.FillEllipse(semiTransBrush, rect);
}
private void button1_Click(object sender, EventArgs e)
{
showGraphic();
}
Настройки для окна рисунка - это просто настройки по умолчанию для изображения из файла, объявленного на панели свойств.
Я смог решить эту проблему с помощью таймера, который запускался кнопкой, а затем выполнял графический рисунок перед тем, как остановиться, однако это казалось ужасным решением, и я хотел сделать это лучше, если он существует, так как это может привести к в отсутствии переносимости на старые компьютеры.
заранее спасибо
2 ответа
Вам необходимо зарегистрировать обработчик для метода Paint в PictureBox и сделать рисование в этом методе. (Примечание: используйте объект Graphics, переданный через параметр PaintEventArgs.) Это гарантирует, что в любой момент, когда PictureBox будет перерисован, ваш код для рисования также будет работать. В противном случае вы просто рисуете что-то, что будет обновлено по любой из причин.
Как только вы зарегистрируетесь в событии Paint, в любое время, когда вы захотите перекрасить, вызовите Invalidate() в PictureBox, и ваш код рисования запустится. Вы можете отслеживать, следует ли рисовать оверлейную графику с помощью закрытой логической переменной-члена.
Когда вы звоните pictureBox1.Invalidate()
он ставит в очередь сообщение о том, что графическое окно должно быть нарисовано. Перед обработкой этого сообщения вы рисуете эллипс поверх текущей картинки. Затем цикл обработки сообщений обрабатывает сообщение рисования от недействительного и затем перерисовывает себя (что стирает ваше изображение)
Чтобы сделать этот (старый и ответивший) вопрос более полным, я добавляю альтернативное решение: иногда вы не хотите перерисовывать картинку при каждом обновлении, например, если рисование сложное и требует времени. Для этих случаев вы можете попробовать следующий подход:
- Создайте новое растровое изображение размером с картинку.
- Рисовать на растровом изображении.
- Установите растровое изображение в качестве изображения.
Например:
// create a new bitmap and create graphics from it
var bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
var graphics = System.Drawing.Graphics.FromImage(bitmap);
// draw on bitmap
SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(128, 0, 0, 255));
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(100,100, 50, 50);
graphics.FillEllipse(semiTransBrush, rect);
// set bitmap as the picturebox's image
pictureBox1.Image = bitmap;
С помощью приведенного выше кода вы можете нарисовать все один раз, и он переживет события перерисовки.