动态更改表单项的位置

时间:2015-01-24 11:52:22

标签: c# .net visual-studio position

我创建了一个表格,其中有一个'矩形'项目的位置需要动态更改,以便不断移动'效果得到了。

enter image description here

我希望黑色矩形在表单的边界内继续移动。我试过这个:

//globally decalred variables
Random locationRandomizer = new Random();
int count = 0;

private void Form1_Load(object sender, EventArgs e)
{
     Thread movementThread = new Thread(new ThreadStart(movementFunction));
     movementThread.Start();
}


public void movementFunction()
{
     try
     {
          int x;
          int y;

          int windowHeight = this.Height;
          int windowWidth = this.Width;

          do
          {
              x = locationRandomizer.Next(1, windowWidth);
              y = locationRandomizer.Next(1, windowWidth);
              animalDot.Location = new Point(x, y);
          }
          while (count == 0);
          }
     catch (Exception ex)
     {

     }
}

但是在加载表单时矩形会移动ONCE,之后不会更改。我做错了什么?

当我删除空的try catch块时,这就是我得到的错误:

跨线程操作无效:控制' shapeContainer1'从创建它的线程以外的线程访问。

2 个答案:

答案 0 :(得分:1)

您收到该错误是因为您正在从非UI线程访问UI元素。您可以通过调用控件上的Invoke方法绕过它,将调用封送回UI线程:

textBox1.Invoke((MethodInvoker)(() => textBox1.Location = new Point(x, y)));

执行一些定期影响用户界面的代码的更好方法是使用System.Windows.Forms.Timer,这是Timer控件,您可以放入设计器中。

订阅Tick事件,该事件在UI线程上运行并避免上述错误。

private void timer_Tick(object sender, EventArgs e)
{
    var x = locationRandomizer.Next(1, Width - animalDot.Width);
    var y = locationRandomizer.Next(1, Height - animalDot.Height);
    animalDot.Location = new Point(x, y);
}

然后在构造函数中,您可以将间隔设置为相对较小的值并启用计时器。

timer.Interval = 100;
timer.Enabled = true;

答案 1 :(得分:0)

你可以制作一个自主的“可移动的”'从Rectange下降并包含在内部计时器实例中的类。当计时器触发时,添加一个'速度'增加到该位置。对于碰撞,你可以下降到一个可碰撞的'当它移动时,迭代所有其他Collidables的集合并触发一个OnCollision'将碰撞对象作为参数的事件,以便您可以决定如何处理与墙壁,其他可移动物体等的碰撞。