0

I am using Windows Forms (.NET Framework) and am trying to make a picture box move a cross a screen. I have tried using timers and this while loop but the image (it's supposed to be a plane) does not appear in the case of the while loop and the use of timers makes it difficult to remove past picture Boxes so they appear to generate a sequence of planes. How can I accomplish this?Does it have something to do with Sleep()?

 private void Button1_Click(object sender, EventArgs e)
    {
        //airplane land
        //drawPlane(ref locx, ref locy);
        //timer1.Enabled = true;
        while (locx > 300)
        {
            var picture = new PictureBox
            {
                Name = "pictureBox",
                Size = new Size(30, 30),
                Location = new System.Drawing.Point(locx, locy),
                Image = Properties.Resources.plane2, //does not appear for some reason

            };

            this.Controls.Add(picture);

            Thread.Sleep(500);

            this.Controls.Remove(picture);
            picture.Dispose();
            locx = locx - 50;


        }
Nick Knapp
  • 23
  • 5
  • 1
    Use a [System.Windows.Forms.Timer](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.timer) to move the Control. You need just one PictureBox: redefine it's position in the `Timer.Tick` event. Don't set the Image property using the `Resources` factory: assign the Image to a Bitmap object, then assign the Bitmap to the Image property when needed and dispose of it when not needed anymore. – Jimi Dec 11 '19 at 11:09

1 Answers1

0

You can use a "Timer" to change the position of the PictureBox regularly. Here is a simple demo that using Timer Class you can refer to.

public partial class Form1 : Form
{

    private System.Timers.Timer myTimer;
    public Form1()
    {
        InitializeComponent();

        myTimer = new System.Timers.Timer(100);
        myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
        myTimer.AutoReset = true;
        myTimer.SynchronizingObject = this;
    }
    private void myTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        pictureBox1.Location = new Point(pictureBox1.Location.X + 1, pictureBox1.Location.Y);
    }

    private void btStart_Click(object sender, EventArgs e)
    {
        myTimer.Enabled = true;
    }
}

The result,

enter image description here

大陸北方網友
  • 3,696
  • 3
  • 12
  • 37
  • @ LarsTech I don't think Winforms Timer is a good choice. It shares thread with the UI, which is likely to cause blocking. – 大陸北方網友 Dec 12 '19 at 02:40
  • The WinForms Timer won't block anything. – LarsTech Dec 12 '19 at 02:44
  • The Winforms Timer is single-threaded. The form will freeze when performing time-consuming operations. And its accuracy can only reach 55 milliseconds. – 大陸北方網友 Dec 12 '19 at 02:49
  • The code you posted would work with a WinForm's Timer. The timer you are using `... is intended for use as a server-based or service component`. Pretty simple really: a WinForm's app should use a WinForm's Timer, especially someone trying to learn to program in it. – LarsTech Dec 12 '19 at 02:58
  • I did not say that Winforms Timer cannot be used. Just personally I don't recommend using it. `a WinForm's app should use a WinForm's Timer`? Sorry, I don't think so. – 大陸北方網友 Dec 12 '19 at 03:02