Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .gif不';直到整个循环结束,才能设置动画?_C#_Multithreading_Winforms_Picturebox - Fatal编程技术网

C# .gif不';直到整个循环结束,才能设置动画?

C# .gif不';直到整个循环结束,才能设置动画?,c#,multithreading,winforms,picturebox,C#,Multithreading,Winforms,Picturebox,我试图通过循环在运行时winform中添加300个按钮。这需要很多时间,所以我想在循环运行时显示一个.gif加载图像。loading.gif仅显示,但在循环完成之前不设置动画。为什么呢 pictureBox1.Load("loading.gif"); pictureBox1.Invalidate(); pictureBox1.Update(); // loop to add buttons this.SuspendLayout(); for (int i = 0; i < 300; i+

我试图通过循环在运行时winform中添加300个按钮。这需要很多时间,所以我想在循环运行时显示一个.gif加载图像。loading.gif仅显示,但在循环完成之前不设置动画。为什么呢

pictureBox1.Load("loading.gif");
pictureBox1.Invalidate();
pictureBox1.Update();

// loop to add buttons
this.SuspendLayout();
for (int i = 0; i < 300; i++)
    // add buttons
this.ResumeLayout();
this.PerformLayout();
pictureBox1.Load(“Load.gif”);
pictureBox1.Invalidate();
pictureBox1.Update();
//循环以添加按钮
这个.SuspendLayout();
对于(int i=0;i<300;i++)
//添加按钮
这是resumeloayout();
这个。执行布局();

循环会阻塞UI线程,因此不会更新
pictureBox1
。解决这个问题有几种可能:

丑陋的一个:使用
Application.DoEvents()按钮创建循环中的每一次(不是每一轮)

或者你可以从计时器中创建按钮,每次10或20个,直到得到300个

或者可以使用基于线程的启动屏幕。但是,重要的是,所有按钮都是由UI线程创建的


或者找到一个不需要300个按钮的更好的解决方案。

可以手动处理动画事件。令人惊讶的是,
OnFrameChanged
事件仍然会触发,这使得制作动画成为可能

public class Form1 : Form {

    Button btn = new Button { Text = "Button", Dock = DockStyle.Top };
    AsyncPictureBox box = new AsyncPictureBox("c:\\temp\\chick_dance.gif") { Dock = DockStyle.Fill };

    public Form1() {
        Controls.Add(box);
        Controls.Add(btn);

        btn.Click += delegate {
            box.AnimateImage = !box.AnimateImage;
            Thread.Sleep(30000);
        };
    }
}

public class AsyncPictureBox : Control {

    Bitmap bitmap = null;
    bool currentlyAnimating = false;
    int frameCount = 0;
    int frame = 0;

    public AsyncPictureBox(String filename) {
        bitmap = new Bitmap(filename);
        this.DoubleBuffered = true;
        frameCount = bitmap.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time);
    }

    public bool AnimateImage {
        get {
            return currentlyAnimating;
        }

        set {
            if (currentlyAnimating == value)
                return;

            currentlyAnimating = value;
            if (value)
                ImageAnimator.Animate(bitmap, OnFrameChanged);
            else
                ImageAnimator.StopAnimate(bitmap, OnFrameChanged);
        }
    }

    // even though the UI thread is busy, this event is still fired
    private void OnFrameChanged(object o, EventArgs e) {
        Graphics g = this.CreateGraphics();
        g.Clear(this.BackColor);
        bitmap.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Time, frame);
        frame = (frame + 1) % frameCount;
        g.DrawImage(bitmap, Point.Empty);
        g.Dispose();
    }

    protected override void Dispose(bool disposing) {
        base.Dispose(disposing);
        if (disposing) {
            if (bitmap != null)
                bitmap.Dispose();
            bitmap = null;
        }
    }
}

如果你注释掉了添加按钮的代码,那么gif会有动画吗?为什么你需要300个按钮?也许有更好的解决办法?@Bijington是的,会的animate@JeffRson它代表一个棋盘,所以我需要大约300个单元格来玩哇,多么大的一个棋盘,而不是正方形。。我只在64个篮板上比赛。请考虑切换到DATAGIDVIEW!!Application.DoEvents()非常有效,非常感谢much@Fish:
DoEvents()
真的不应该被建议,这是解决这个问题最糟糕的方式(