0

I want to move picturebox with thread programming. Also, I want to get Picturebox's count with a Textbox in my solution, but it's my first try so I have problems with it. Could you please help me?

Thread th;
        public void F_Thread()
        {
            for (int i = 0; i < Convert.ToInt16(textBox1.Text); i++)
            {
                this.pictureBox1.Left = this.pictureBox1.Left - 10;
                Thread.Sleep(100);
            }
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            th = new Thread(F_Thread);
            th.Start();
        }
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Sarah
  • 3
  • 1
  • You can't use threads with UI. Use a timer or `await`. – SLaks May 17 '16 at 15:33
  • 1
    any attempt to manipulate a UI element from outside the UI thread must be done with Invoke. – TaW May 17 '16 at 15:38
  • Thanks for your comment,I tried it with Timer,but I should write this with Threads!! do you know how can I write it?? – Sarah May 17 '16 at 15:45

1 Answers1

2

Here is a cheap, minimal example of using Invoke to change a property of a control from a different thread:

public void F_Thread()
{
    for (int i = 0; i < Convert.ToInt16(textBox1.Text); i++)
    {
        if (pictureBox1.InvokeRequired ) 
            this.Invoke(new UpdatePBInvoker(UpdatePB), -10);

        Thread.Sleep(100);
    }
}

delegate void UpdatePBInvoker(int moveX);

private void UpdatePB(int moveX)
{
    pictureBox1.Left = pictureBox1.Left + moveX;
}

Feel free to add more parameters; just make sure to keep the signatures of the function and the delegate the same:

    delegate void UpdatePBInvoker(Control ctl, int moveX);

    private void UpdatePB(Control ctl, int moveX)
    {
        ctl.Left = ctl.Left + moveX;
    }

Call the 2nd version like this:

.. this.Invoke(new UpdatePBInvoker(UpdatePB), pictureBox1, -10);

Note the the check if ( someControl.InvokeRequired ) is optional and often added to allow for the option of not calling the function from a different thread; for theses cases one usually adds an else branch with the direct call: UpdatePB(...)

Also note that the thread may still run when you close the Form. To prevent errors make sure to abort it, maybe like this:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if ((th!= null && th.IsAlive) th.Abort();
}

If your thread would do more complicated things, especially aquiring locks, it should not be aborted but given a chance to finish and close itself, usually by setting a global flag. But in this case it should work ok. Also see MSDN on this topic..

Community
  • 1
  • 1
TaW
  • 53,122
  • 8
  • 69
  • 111
  • Note the added remark about closing the form! Also: If you are happy with an answer, please consider [accepting](http://stackoverflow.com/help/accepted-answer) it..! – TaW May 17 '16 at 16:03