Search code examples
c#winformspaint

Using paint method to create movement on form - not working


I am trying to draw a moving rectangle and circle on a form using the paint method. A button should start the process. 2nd press should end the program. The once variable is a global Boolean set to True on start. X1 is a global int, set to 10 on start. Up is a global Boolean, set to true on start.

Each iteration the X1 variable is increased until 100, going down to 10, endlessly.

I am observing two problems as following.

  1. No movement of the drawing on the form
  2. No control on the form once the program starts

Following is the code:

private void Form1_Paint(object sender, PaintEventArgs e)  
{  

    Pen red = new Pen(Color.Red,3);  
    Rectangle rect = new Rectangle(x1, x1, x1, x1);  
    Rectangle circle = new Rectangle(x1+10, x1 + 10, x1 + 50, x1 + 50);  

    //Graphics g = e.Graphics;  
    Graphics g = CreateGraphics();  
    g.DrawRectangle(red,rect);  
    g.DrawEllipse(red, circle);  

    red.Dispose();  
    g.Dispose();             
}  

private void button2_Click(object sender, EventArgs e)  
{            
    if (once)             
        once = false;              
    else  
        Environment.Exit(0);  

    while (true)  
    {  
        if (up )  
        {  
            x1 += 10;  
            if (x1 > 100)  
                up = false;  
        }  
        else  
        {  
            x1 -= 10;  
            if (x1 <= 10)  
                up = true;  
        }  
        this.Invalidate();  
        Thread.Sleep(500);  
    }                      
}  

Solution

  • Here is one way to achieve this task using System.Windows.Forms.Timer, please see changes and comments:

    private int x1 = 4;
    System.Windows.Forms.Timer timer;
    private bool once = true;
    private bool up = false;
    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        // use e.Graphics
        Graphics g = e.Graphics;
        Pen red = new Pen(Color.Red, 3);
        Rectangle rect = new Rectangle(x1, x1, x1, x1);
        Rectangle circle = new Rectangle(x1 + 10, x1 + 10, x1 + 50, x1 + 50);
        g.DrawRectangle(red, rect);
        g.DrawEllipse(red, circle);
    
        red.Dispose();
        g.Dispose();
    }
    
    private void button2_Click(object sender, EventArgs e)
    {
        if (once)
        {
            once = false;
            Init();
        }
        else
        {
            if (timer != null)
            {
                timer.Stop();
                timer.Dispose();
                timer = null;
            }
            // you can exit app...
             Application.Exit();
        }
    }
    
    private void Init()
    {
        if (timer == null)
        {
            timer = new Timer();
            timer.Interval = 500;
            timer.Tick += timer_tick;
        }
    
        timer.Start();
    }
    
    private void timer_tick(object sender, EventArgs e)
    {
        if (up)
        {
            x1 += 10;
            if (x1 > 100)
                up = false;
        }
        else
        {
            x1 -= 10;
            if (x1 <= 10)
                up = true;
        }
        this.Invalidate();
    }