Search code examples
c#winformsbitmappanelsystem.drawing

Drawing to a panel using a bitmap as a buffer


I have been learning about drawing to panels using bitmaps. I thought I would run a trial program to simply turn a white panel black. (May seem a complicated way of doing it but this is just to test the basics) My program is as follows:

public partial class Form1 : Form
{
    private Bitmap buffer = new Bitmap(100,100);

    public Form1()
    {
        InitializeComponent();
    }

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
       e.Graphics.DrawImageUnscaled(buffer, Point.Empty);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < 100; i++)
        {
            for (int j = 0; j < 100; j++)
            {
                buffer.SetPixel(i, j, Color.Black);
            }
        }
    }
}

When I run it and press the button the panel does not seem to change. Any Idea where I am going wrong. Thank you in advance.


Solution

  • You have to invalidate the panel's client area so that Windows will force a repaint. But there are some other issues:

    1. FillRectangle will do a much more efficient job than painting each pixel in a loop, as @Tony suggested.
    2. You might hit concurrency issues if the panel is invalidated before buffer is ready to be displayed. Be sure that the bitmap generation is isolated from its presentation.

    These suggestions are summarized (but not tested) as follows:

    private void button1_Click(object sender, EventArgs e)
    {
        Bitmap tempBuffer = new Bitmap(100, 100);
    
        using (Graphics g = Graphics.FromImage(tempBuffer))
        using (SolidBrush blackBrush = new SolidBrush(Color.Black))
        {
            g.FillRectangle(blackBrush, new Rectangle(0, 0, tempBuffer.Width-1, tempBuffer.Height-1);
        }
    
        buffer = tempBuffer;
        panel1.Invalidate();
    }