3

I want when I click button, add one rectangle to the form
I can add in form paint how much I want but I can't add shape like rectangle by click button and I searched about it but I didn't find a solution for it
is here somebody know how to do it?

This is my code in form paint

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
            locationX = locationX + 20;
            locationY = locationY + 20;
            e.Graphics.DrawRectangle(Pens.Black, 
                       new Rectangle(10 + locationX, 10 + locationY, 50, 30));
    }

and this one is my button code

    private void button1_Click(object sender, EventArgs e)
    {
        this.Paint += Form1_Paint;
    }

but its not working when I click button. why its not working?

Cyril Gandon
  • 16,830
  • 14
  • 78
  • 122
Salmani
  • 41
  • 1
  • 1
  • 7
  • Your button click is just adding an event handler, it is not causing that event to be triggered. – kidshaw Jun 13 '15 at 19:45
  • 1
    Replace `this.Paint += Form1_Paint;` by `Invalidate();` Make sure the Paint event is hooked up. (once). To add more and more Rectangles to need to add their coordinates to a List! – TaW Jun 13 '15 at 20:32

2 Answers2

8

The line

 this.Paint += Form1_Paint;

Associate the event Paint of your Form to your function Form1_Paint. It doesn't trigger it. This is something you want to do only 1 time, not everytime you hit a button.

To trigger the Paint event, the usual way is to call the Invalidate() method of the Form class. In fact, Invalidate is a method of Control. But Form derivate from Control, so we have access to the method in Form too.

So the right way to trigger a repaint in Windows Forms is to put the subscribe in the Load method :

private void Form1_Load(object sender, EventArgs e)
{
    this.Paint += Form1_Paint;
}

It should already be hidden in the auto generated code. Your method Form1_Paint is ok.

Finally, the button click method should be :

private void button1_Click(object sender, EventArgs e)
{
    this.Invalidate(); // force Redraw the form
}

From the doc :

Invalidate() : Invalidates the entire surface of the control and causes the control to be redrawn.

Edit :

With this method, you can draw only 1 rectangle at a time, because the whole surface is redrawn, so the surface is completly erase, and then it draws only what you asked in the Form1_Paint method.

For the answer on how to draw multiple rectangles, you should create a List of Rectangle. At each click button, you add a Rectangle to the list, and you redraw all the rectangles.

List<Rectangle> _rectangles = new List<Rectangle>();
private void button1_Click(object sender, EventArgs e)
{
    locationX = locationX + 20;
    locationY = locationY + 20;
    var rectangle = new Rectangle(locationX, locationY, 50, 30));
    this._rectangles.Add(rectangle);
    this.Invalidate(); // force Redraw the form
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
    foreach(var rectangle in this._rectangles)
    {
        e.Graphics.DrawRectangle(Pens.Black, rectangle);
    }
}
Cyril Gandon
  • 16,830
  • 14
  • 78
  • 122
  • thanks but there is one more problem, now when i click button it work but it delete the last shape it made i want the rectangles made before click not delete and just one to them by every click – Salmani Jun 14 '15 at 07:12
  • it worked, thank you a lot and i think this is the first answer of make it from button ;) and please vote up my question – Salmani Jun 14 '15 at 20:58
-2

to call a method you need the parenthesys.

private void button1_Click(object sender, EventArgs e)
{
    Form1_Paint(sender, e);
}
maraaaaaaaa
  • 7,749
  • 2
  • 22
  • 37
  • 3
    This will not work (nor compile) since `Paint` needs a very special parameter. `Sender` obvioulsy shoud be __not__ button but the form `this`. __But__ the `PaintEventArgs` are not things you should try to 'create'... – TaW Jun 13 '15 at 23:35