Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I draw over a panel in C#?

Hey, I need to do my drawing over a panel in C# but without placing my drawing code inside "panel1_Paint", how can I do that ?? BTW, I'm using WinForms.

Update : I forgot to make something clear, I need not to place my drawing code inside paint handler, because I need to start drawing depending on buttons' events.

like image 332
Lisa Avatar asked Apr 09 '10 23:04

Lisa


2 Answers

Usually you do all your drawings in the paint event handler. If you want to do any update (if a user clicks on the panel for example) you have to defer that action: you store the required data (coordinates where the user clicked) and force a redraw of the control. This causes the paint event to be fired, where you can then draw things you stored before.

Another way would be (if you really want to draw outside of the 'panel1_Paint' event handler) to draw inside a buffer image, and copy the image to the controls graphics object in the paint event handler.

Update:

An example:

public class Form1 : Form
{
    private Bitmap buffer;

    public Form1()
    {
        InitializeComponent();

        // Initialize buffer
        panel1_Resize(this, null);
    }

    private void panel1_Resize(object sender, EventArgs e)
    {
        // Resize the buffer, if it is growing
        if (buffer == null || 
            buffer.Width < panel1.Width || 
            buffer.Height < panel1.Height)
        {
            Bitmap newBuffer = new Bitmap(panel1.Width, panel1.Height);
            if (buffer != null)
                using (Graphics bufferGrph = Graphics.FromImage(newBuffer))
                    bufferGrph.DrawImageUnscaled(buffer, Point.Empty);
            buffer = newBuffer;
        }
    }

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        // Draw the buffer into the panel
        e.Graphics.DrawImageUnscaled(buffer, Point.Empty);
    }



    private void button1_Click(object sender, EventArgs e)
    {
        // Draw into the buffer when button is clicked
        PaintBlueRectangle();
    }

    private void PaintBlueRectangle()
    {
        // Draw blue rectangle into the buffer
        using (Graphics bufferGrph = Graphics.FromImage(buffer))
        {
            bufferGrph.DrawRectangle(new Pen(Color.Blue, 1), 1, 1, 100, 100);
        }

        // Invalidate the panel. This will lead to a call of 'panel1_Paint'
        panel1.Invalidate();
    }
}

Now the drawn images wont be lost, even after a redraw of the control, because it only draws out the buffer (the image, saved in the memory). Additionally you can draw things anytime a event occurs, by simply drawing into the buffer.

like image 187
Philip Daubmeier Avatar answered Sep 23 '22 21:09

Philip Daubmeier


Try this: what happens when you come back to your application, after using another application that covers up part or all of your window?

What you should be doing is rendering what you need to an offscreen bitmap, called a buffer. You'll render the image whenever you want, in response to anything that changes what the image should display. Then, from the panel's paint event, you'll copy from that buffer to the panel.

Graphics programming is a lot of fun. It might seem like there are a lot of details to consider, but there aren't many once you learn them. But this is an area where a slapdash approach will show through, and can make an application feel very unreliable and unprofessional.

like image 36
overslacked Avatar answered Sep 23 '22 21:09

overslacked