이 잘못된 것 같다 : 이것은 루프 i < 20
동안 것
for (int i = b; i < 20; i--)
{
pictureBox1.Top = i;
System.Threading.Thread.Sleep(20);
}
. 그러나 코드에서 Top == 20
에 도달하면 다른 그림을 보여주고 싶다는 것을 알 수 있습니다. 그래서 나는 i >= 20
이어야하고 if
은 Top <= 20
이어야한다고 생각합니다.
또한 디스플레이를 새로 고침하지 않습니다. 루프와 Sleep
으로 인해 UI 업데이트가 없습니다. Cobra_Fast에서 알 수 있듯이
이 추가하기 전에
Sleep
:
this.Invalidate();
this.Refresh();
, 다음 (나는 또한 약간 명확하게하기 위해 코드를 수정 한) 작업을해야 그것을 요약하면 :
private void button1_Click(object sender, EventArgs e)
{
while (pictureBox1.Top >= 20)
{
pictureBox1.Top = pictureBox1.Top - 1;
this.Invalidate();
this.Refresh();
System.Threading.Thread.Sleep(20);
}
// Here you KNOW that the picture box is at y-position 20, so there's not need
// for the IF
pictureBox1.Visible = false;
pictureBox2.Visible = true;
}
위 코드의 문제점은 UI를 차단한다는 것입니다.
private void AnimationStep(object source, ElapsedEventArgs e)
{
// The following code needs to be executed in the context of the UI thread.
// We need to use this.Invoke in Forms or this.Dispatcher.Invoke in WPF
this.Invoke((Action)delegate()
{
// Move picture. Note that we don't need to update the display here
// because the UI thread gets time to do its work while the timer waits
// to fire below
if (pictureBox1.Top > 20)
pictureBox1.Top--;
// Show other picture maybe. I use <= here because initially, the
// position of the picture box may already smaller than 20.
if (pictureBox1.Top <= 20)
{
pictureBox1.Visible = false;
pictureBox2.Visible = true;
}
// Or let the timer fire again if we still need to animate
else
{
(source as System.Timers.Timer).Start();
}
}
}
이 같이 작동 다음과 같습니다 :
private void button1_Click(object sender, EventArgs e)
{
// Create a threaded timer
System.Timers.Timer animationTimer = new System.Timers.Timer();
animationTimer.Interval = 20;
animationTimer.AutoReset = false; // Only one Ping! We'll activate it if necessary
animationTimer.Elapsed += new ElapsedEventHandler(AnimationStep);
animationTimer.Start();
// Disable the button also, because we don't want another timer instance to
// interfere with our running animation
button1.Enabled = false;
}
을 다음 타이머 화재가 때 호출하는 이벤트를 생성 : 타이머가 만들어집니다 다음과 같이 반응을 유지하기 위해, 나는 타이머를 사용하십시오 20ms 후 한 번 발사. 그런 다음 그림을 한 픽셀 위로 이동 한 다음 애니메이션이 끝나면 다른 그림을 표시하거나 다른 픽셀 위로 그림을 이동하기 위해 타이머를 다시 시작합니다.
이렇게하면 UI가 반응을 유지하면서도 그림을 애니메이션으로 만들 수 있습니다. 단점은 윈도우가 움직이거나 다른 "작업"이 UI 스레드에 의해 수행되어야 할 경우를 대비하여 애니메이션이 부드럽 지 않을 수도 있다는 것입니다.
그것의 어느 부분이 잘못 되었습니까? 그것이 어떻게 행동 할 것이라고 기대되는 것과 비교하면 지금 어떻게 행동하고 있습니까? –
오류가 없으며 작동하지 않습니다. 버튼을 클릭해도 아무런 변화가 없습니다. – Noterezeck
디버깅 프로세스의 일부로 코드를 밟았습니까? 지금은 누구나 추측 할 수 있습니다. 이 이벤트 처리기가 전혀 실행되지 않을 수도 있습니다. 처음 시작했을 때 맞았는지 확인한 후 단계별로 진행하고 모든 정수 값을 확인하십시오. –