Проблема с отрисовкой WinForms (какую очевидную вещь я упускаю)

#c# #winforms #graphics

#c# #winforms #графика

Вопрос:

Когда я запускаю следующий код, изображение, которое я загрузил в объект MyPictureBox, на короткое время мигает, но затем форма немедленно перезаписывается стандартным цветом фона Windows.

  • Я получаю сообщения в том, что кажется правильным порядком.
  • Я попытался удалить каждую из базовых.OnPaint (), но это не решает проблему.
  • Я попробовал двойной буфер; не ожидал, что это что-то изменит, и это не помогло.

Я знаю, что мне не хватает чего-то действительно очевидного. (P.S. в форме нет других элементов управления, кроме MyPictureBox, который я добавляю.)

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

namespace Outlines {

    public partial class Form1 : Form {

        public MyPictureBox MPB;

        public Form1() {
            InitializeComponent();
            MPB = new MyPictureBox("Benny.png");
            this.Controls.Add(MPB);
        }

        private void Form1_Load(object sender, EventArgs e) {
            Console.WriteLine("Form1:Load");
        }

        protected override void OnResizeEnd(EventArgs e) {
            Console.WriteLine("Form1:ResizeEnd");
            base.OnResizeEnd(e);
            MPB.Size = new Size(this.ClientRectangle.Width, this.ClientRectangle.Height);
            this.Invalidate(true);
        }

        protected override void OnClick(EventArgs e) {
            Console.WriteLine("Form1:OnClick");
            base.OnClick(e);
            this.Invalidate(true);
        }

        protected override void OnPaint(PaintEventArgs e) {
            Console.WriteLine("Form1:OnPaint");
            base.OnPaint(e);
        }

    }

    public class MyPictureBox : PictureBox {

        private Bitmap _bitmap;

        public MyPictureBox(string pathName) {
            _bitmap = new Bitmap(pathName);
            this.Size = new Size(500, 500);
            this.Enabled = true;
            this.Visible = true;
        }

        protected override void OnPaint(PaintEventArgs pe) {
            Console.WriteLine("MPB:OnPaint");
            base.OnPaint(pe);
            var graphics = this.CreateGraphics();
            graphics.Clear(Color.Gray);
            if (_bitmap == null)
                return;
            graphics.DrawImage(_bitmap, new Point(0, 0));
            graphics.Dispose();
        }

        protected override void OnResize(EventArgs e) {
            Console.WriteLine("MPB:OnResize");
            base.OnResize(e);
        }

    }

}
  

Комментарии:

1. Вы пробовали устанавливать изображение в методе загрузки?

2. Control.CreateGraphics(); используется в конкретных, определенных ситуациях (в основном, для измерения материала). Не используйте его для отрисовки и никогда не сохраняйте его (он станет недействительным, как только элемент управления будет перерисован — это происходит постоянно). Всегда рисуйте в переопределенном OnPaint() методе или обработчике события Paint (или DrawItem и friends), используя предоставленный графический объект (как PaintEventArgs).

Ответ №1:

Не создавайте новый графический объект внутри метода OnPaint; используйте тот, который указан в аргументе PaintEvents. Как указывает @ Jimi выше…

Управление.CreateGraphics(); используется в конкретных, определенных ситуациях (в основном, для измерения материала). Не используйте его для отрисовки и никогда не сохраняйте его (он станет недействительным, как только элемент управления будет перерисован — это происходит постоянно). Всегда рисуйте в переопределенном методе OnPaint () или обработчике события Paint (или DrawItem и friends), используя предоставленный графический объект (как PaintEventArgs).

Комментарии:

1. Другое маловероятное использование — рисовать непостоянные элементы, такие как линия резиновой ленты или прямоугольник и т.д..