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);
}
}