由于某种原因,这冻结了程序:
private void Form1_Shown(object sender, EventArgs e)
{
int x = 1;
var frame1 = pictureBox2.BackgroundImage;
var frame2 = pictureBox3.BackgroundImage;
while(x < 2)
{
pictureBox1.BackgroundImage = frame1;
pictureBox1.BackgroundImage = frame2;
}
}
为什么?
pictureBox2
包含第一帧,pictureBox3
包含第二帧
pictureBox1
包含'动画'。 (如代码所示)
编辑:我不希望它为 ONCE 制作动画,我希望它能为 FOREVER设置动画。
答案 0 :(得分:2)
这是单程......
使用async
标记您的已显示()事件,然后在帧之间使用await Task.Delay()
:
private async void Form1_Shown(object sender, EventArgs e)
{
bool first = true;
var frame1 = pictureBox2.BackgroundImage;
var frame2 = pictureBox3.BackgroundImage;
while (true)
{
pictureBox1.BackgroundImage = first ? frame1 : frame2;
first = !first;
await Task.Delay(500); // 1/2 second delay <-- set it to your desired delay between frames
}
}
----------编辑----------
使用Timer和IEnumerator的替代方法。如果你有两个以上的框架,这将是一个很好的方法:
private IEnumerator<Image> frames;
private System.Windows.Forms.Timer tmr;
private void Form1_Shown(object sender, EventArgs e)
{
List<Image> lstFrames = new List<Image>();
lstFrames.Add(pictureBox2.BackgroundImage);
lstFrames.Add(pictureBox3.BackgroundImage);
lstFrames.Add(pictureBox4.BackgroundImage);
// etc...
frames = lstFrames.GetEnumerator();
DisplayNextFrame();
tmr = new System.Windows.Forms.Timer();
tmr.Interval = 500;
tmr.Tick += Tmr_Tick;
tmr.Start();
}
private void Tmr_Tick(object sender, EventArgs e)
{
DisplayNextFrame();
}
private void DisplayNextFrame()
{
if (!frames.MoveNext())
{
frames.Reset();
frames.MoveNext();
}
pictureBox1.BackgroundImage = frames.Current;
}
答案 1 :(得分:1)
在您的情况下,x
的值始终为1
,这就是while循环继续迭代并且程序进入无限循环的原因。
解决方案:
您应该使用BackgroundWorker
将代码作为Asynchronous
在表单中插入新的BackgroundWorker
。
将您的函数插入DoWork
事件。
private void bWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var frame1;
var frame2;
if (pictureBox2.InvokeRequired) { pictureBox2.Invoke((MethodInvoker)delegate { frame1 = pictureBox2.BackgroundImage; }); } else { frame1 = pictureBox2.BackgroundImage; }
if (pictureBox3.InvokeRequired) { pictureBox3.Invoke((MethodInvoker)delegate { frame2 = pictureBox3.BackgroundImage; }); } else { frame2 = pictureBox3.BackgroundImage; }
while (true)
{
if (pictureBox1.InvokeRequired) { pictureBox1.Invoke((MethodInvoker)delegate { pictureBox1.BackgroundImage = frame1; }); } else { pictureBox1.BackgroundImage = frame1; }
if (pictureBox1.InvokeRequired) { pictureBox1.Invoke((MethodInvoker)delegate { pictureBox1.BackgroundImage = frame2; }); } else { pictureBox1.BackgroundImage = frame2; }
}
}
现在,开始运行BackgroundWorker
。
bWorker1.RunWorkerAsync();
答案 2 :(得分:0)
为您的animiation创建一个并行线程:
private void Form1_Shown(object sender, EventArgs e)
{
//create parallel thread
Thread animationThread = new Thread(Animation);
animationThread.Start();
}
//create a new method for animation to run on a parallel thread
private void Animation()
{
int x = 1;
var frame1 = pictureBox1.Image;
var frame2 = pictureBox2.Image;
while (x < 2)
{
this.Invoke(new Action(() => pictureBox3.Image = frame1));
this.Invoke(new Action(() => pictureBox3.Refresh()));
Thread.Sleep(100); //you must keep a dealy other wise it will consume too much processing
this.Invoke(new Action(() => pictureBox3.Image = frame2));
this.Invoke(new Action(() => pictureBox3.Refresh()));
}
}
答案 3 :(得分:0)
你的循环永远运行,永远不会终止。
while (x < 2)
循环没有终止条款,因此你的程序会冻结; x
总是小于2.如果您不允许应用程序呼吸,它就会冻结。试试这个:
private void Form1_Shown(object sender, EventArgs e)
{
var frame1 = pictureBox2.BackgroundImage;
var frame2 = pictureBox3.BackgroundImage;
while(true)
{
pictureBox1.BackgroundImage = frame1;
Application.DoEvents(); // give the thread room to run background tasks
pictureBox1.BackgroundImage = frame2;
Application.DoEvents(); // give the thread room to run background tasks
}
}
DoEvents()只是一个选项,可能不是最适合您的情况。你可能最好写一个适当的计时器,它可以在两个图像之间切换40毫秒或者你的动画速度。
答案 4 :(得分:0)
我认为你应该在循环中的frame1和frame2之间添加一些时间延迟,以查看动画效果。