1

I am trying to draw some ellipse in a picturebox that contains a PNG on a formload in c#. When I execute the code down below, I see my ellipses for half of a second, then I don't see them no more.

When I click on my picturebox, I am able to draw an ellipse however, when I minimize the form, they don't appear no more.

I've read that you shouldn't put your drawing code in the formload but rather in the OnPaint method, which is what I did. I don't know what to try anymore. thank you. (Be aware that I've left some code commented to show what I've tried).

public partial class FormParterre : Form
{
    Graphics g;
    float circleSize = 15;
    //Brushes rouge = new Brushes (Brushes.Red);

    ReservationBilletSiegeDAO reservationBilletSiegeDAO = new ReservationBilletSiegeDAO();
    SiegeDAO siegeDAO = new SiegeDAO();

    List <Siege> sieges;
    List<ReservationBilletSiege> rbs;
    ReservationBillet reservationBillet = new ReservationBillet();
    ReservationBilletSiege reservationBilletSiege;

    SolidBrush semiTransBrush;


    public FormParterre()
    {
        InitializeComponent();
        pictureBox1.Image = new Bitmap("./parterre.png");
        g = pictureBox1.CreateGraphics();


    }

    public FormParterre(ReservationBillet rb)
    {
        reservationBillet = rb;
        pictureBox1.Image = new Bitmap("./parterre.png");
        g = pictureBox1.CreateGraphics();



        InitializeComponent();
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        // do nothing! prevents flicker
    }

    protected override void OnPaint(PaintEventArgs e)
    {

        sieges = siegeDAO.readAll();

        rbs = reservationBilletSiegeDAO.readAll();

        foreach (ReservationBilletSiege reservationBilletSiegeTMP in rbs)
        {
            Console.WriteLine(reservationBilletSiegeTMP.toString());
            int x = siegeDAO.read(reservationBilletSiegeTMP.idSiege).xValeur;
            int y = siegeDAO.read(reservationBilletSiegeTMP.idSiege).yValeur;
            float xx = (float)x;
            float yy = (float)y; 
            Console.WriteLine("le x: " + xx);
            Console.WriteLine("le y: " + yy);


              /*e.Graphics.FillRectangle(new SolidBrush(BackColor), e.ClipRectangle);*/
            g.FillEllipse(new SolidBrush(Color.FromArgb(128, 0, 0, 255)), xx - circleSize / 2, yy - circleSize / 2, circleSize,                                     circleSize);
        }

    }

    private void pictureBox1_Click(object sender, EventArgs e)
    {  
        MouseEventArgs me = (MouseEventArgs)e;
        txtX.Text = me.X.ToString();
        txtY.Text = me.Y.ToString();

        Console.WriteLine("click"); 

        g.FillEllipse(new SolidBrush(Color.FromArgb(128, 0, 0, 255)), float.Parse(txtX.Text) - circleSize / 2, float.Parse(txtY.Text) - circleSize / 2, circleSize, circleSize);





    }

    private void FormParterre_Shown(object sender, EventArgs e)
    {

    }

    private void FormParterre_Load(object sender, EventArgs e)
    {

        /*sieges = siegeDAO.readAll();
        //semiTransBrush = new SolidBrush(Color.FromArgb(128, 0, 0, 255));



        rbs = reservationBilletSiegeDAO.readAll();

        foreach (ReservationBilletSiege reservationBilletSiegeTMP in rbs)
        {
            Console.WriteLine(reservationBilletSiegeTMP.toString());
            int x = siegeDAO.read(reservationBilletSiegeTMP.idSiege).xValeur;
            int y = siegeDAO.read(reservationBilletSiegeTMP.idSiege).yValeur;
            float xx = (float)x;
            float yy = (float)y; 
            Console.WriteLine("le x: " + xx);
            Console.WriteLine("le y: " + yy);

            g.FillEllipse(new SolidBrush(Color.FromArgb(128, 0, 0, 255)), xx - circleSize / 2, yy - circleSize / 2, circleSize, circleSize);
        }*/
    }


}
Eric
  • 363
  • 2
  • 9
  • 24

1 Answers1

5

You need to paint in the OnPaint method using the PaintEventArgs.Graphics property which is passed to you. If you want to paint on the PictureBox you can try subscribing to its Paint event and painting there.

This works for me:

public void Form1()
{
    InitializeComponent();

    pictureBox1.Paint += pictureBox1_Paint;
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.FillEllipse(Brushes.Red, pictureBox1.ClientRectangle);
}
Trevor Elliott
  • 11,292
  • 11
  • 63
  • 102
  • This is gonna sound stupid but how do I go about "subscribing to the PictureBox Paint event using the Visual Studio Designer"? – Eric Nov 15 '13 at 22:11
  • 1
    Select the PictureBox. In the Properties Pane (bottom right by default), click on the "Lightning Bolt" Icon. Find the "Paint" entry and Double Click in the space to the Right of it. – Idle_Mind Nov 15 '13 at 22:31
  • 1
    Edited to also show the code-based way of subscribing to an event. – Trevor Elliott Nov 15 '13 at 23:30
  • Thanks for the help Trevor. Now, on formload, I see my ellipses but when I click on an area to create an ellipse, it appears for half a second then dissapears. Something in my mouse click code is not right. – Eric Nov 18 '13 at 14:24
  • You need to keep track of all of the ellipses that need to be painted. When you need to redraw the scene you need to call `Invalidate()` on the control you're painting and it will call a Paint event. In the Paint event you need to draw all ellipses that you expect to see. Every time Paint is called the entire canvas is expected to be wiped away completely so you need to redraw everything. Perhaps create a class to represent your Ellipse which stores the color and rectangle in which it resides? Then create a List of that class and draw it on each Paint event. – Trevor Elliott Nov 18 '13 at 14:28
  • Oh Great! Now I understand. Instead of a list, I will use my existing database and update it when there is a mouse click. Then the paint event will go see in the database! There's only one little problem left and it's that the form outside the picture box is tranparent so I see my desktop! Thanks again! – Eric Nov 18 '13 at 15:05
  • Make sure you're painting the background. You usually want to use the Graphics `Clear()` method to fill with a color. – Trevor Elliott Nov 18 '13 at 16:03