我想用线程编程移动picturebox。此外,我希望在我的解决方案中使用文本框来计算Picturebox,但这是我的第一次尝试,所以我遇到了问题。你能帮我吗?
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();
}
答案 0 :(得分:2)
以下是使用Invoke从不同线程更改控件属性的一个便宜的最小示例:
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;
}
随意添加更多参数;只需确保保持函数和委托的签名相同:
delegate void UpdatePBInvoker(Control ctl, int moveX);
private void UpdatePB(Control ctl, int moveX)
{
ctl.Left = ctl.Left + moveX;
}
像这样调用第二个版本:
.. this.Invoke(new UpdatePBInvoker(UpdatePB), pictureBox1, -10);
注意,检查if ( someControl.InvokeRequired )
是可选的,并且经常被添加以允许不从另一个线程调用该函数的选项;对于这些案例,通常会在直接调用中添加else
分支:UpdatePB(...)
请注意,关闭表单时,该主题可能仍然运行。为了防止错误,请确保中止,可能是这样的:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if ((th!= null && th.IsAlive) th.Abort();
}
如果您的主题会执行更复杂的操作,尤其是获取锁定,则应该不中止但是有机会完成并关闭自己,usually通过设置全局标志。但在这种情况下,它应该工作正常。另请参阅此主题的MSDN ..