如何从另一个线程填充面板?

时间:2014-11-24 08:39:46

标签: c# multithreading winforms

我已经尝试过几种方法来做这件事,但我似乎无法找到一个可行的方法。我有一个GUI,当你按下一个按钮时,所有的处理都是在一个线程上完成的。例如,如果我有以下代码:

    public void coolMethod()
    {
        int a = 0;
        while (a != 20)
        {
            addPicturebox();
            a++;
            Thread.Sleep(1000);
        }
    }

    int width = 3;
    int height = 3;
    int imgCounter = 0;

    public void addPicturebox()
    {
        PictureBox pb = new PictureBox();
        pb.Size = new Size(50, 50);
        pb.Location = new Point(width, height);
        pb.ImageLocation = @"C:\Users\User1\Pictures\white.png";
        pb.Show();

        panel1.Controls.Add(pb);
        imgCounter++;

        width += 53;

        if (imgCounter == 5)
        {
            height += 53;
            width = 3;
            imgCounter = 0;
        }
    }`

但是coolMethod()正在另一个线程上运行,我无法在不同的线程上更新/添加控件。

有没有人有一个解决方案,我可以在thread1上运行coolMethod但是一旦它调用addPicturebox()这个方法将在gui线程上运行并暂停thread1直到方法完成或任何其他建议。

非常感谢,如果可以的话。如果已经回答了这个问题,那么您可以将该页面链接到我,因为我查看了很多但是找不到可以在这种情况下工作的示例。

3 个答案:

答案 0 :(得分:1)

最简单的方法是使用lambda invoke表达式,只需替换

addPicturebox();

panel1.Invoke((MethodInvoker)(() =>
{
    addPicturebox();
}));

它也像你想要的那样工作。新线程暂停,直到添加控件

答案 1 :(得分:0)

如果我理解正确,你想从另一个线程改变GUI?

如果是这种情况,则需要使用Dispatcher

http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher(v=vs.110).aspx

答案 2 :(得分:0)

panel1.Invoke((Action)delegate { addPicturebox(); });