2014-05-05 110 views
0

我想製作一個程序,每5秒顯示一個圖像,然後暫停1秒,然後顯示下一個。但我有一個暫停圖像的問題。如果我有消息框代碼,它停止顯示圖像,我必須按OK才能繼續,但如果不顯示圖像,則會跳到最後一張圖像。請幫助,我必須添加在我的代碼才能正常工作?用c暫停圖像#

private void button1_Click(object sender, EventArgs e) 
{ 
    string[] arr1 = 
     new string[] { "water", "eat", "bath", "tv", "park", "sleep" }; 

    for (int i = 0; i < 6; i++) 
    { 
     button1.BackgroundImage = 
      (Image)Properties.Resources.ResourceManager.GetObject(arr1[i]); 
     new SoundPlayer(Properties.Resources.nero).Play(); 
     MessageBox.Show(arr1[i].ToString()); 

     Thread.Sleep(5000); 
    } 
} 
+0

我很困惑這裏的消息框的用途是什麼,但是'Thread.Sleep'不會是正確的解決方案。 –

+0

消息框可能只是一個調試解決方案,以查看循環是否運行。當然,在關閉該框之後,UI將被刷新,而沒有消息框的情況並非如此。 –

+0

消息框不是我需要的東西,它只是用於測試 – marios

回答

2

問題是UI線程沒有機會更新顯示。那就是:圖片顯示爲,但UI不更新。

一個不那麼好的,黑客是使用Application.DoEvents讓這樣的UI更新本身:

for (int i = 0; i < 6; i++) 
{ 
    button1.BackgroundImage = (Image)Properties.Resources.ResourceManager.GetObject(arr1[i]); 
    Application.DoEvents(); 

    new SoundPlayer(Properties.Resources.nero).Play(); 

    Thread.Sleep(5000); 
} 

因此,按當另一個(更清潔)的解決辦法是改變你的邏輯按鈕啓動一個定時器,用於更改圖片,每5秒運行一次。我假設你正在使用Windows窗體,所以你可以把一個表單上名爲timerTimer,附加一個事件處理程序Elapsed事件,然後使用此:

// These are instance members outside any methods!! 
private int currentImageIndex = 0; 
string[] arr1 = new string[] { "water", "eat", "bath", "tv", "park", "sleep" }; 

private void button1_Click(object sender, EventArgs e) 
{ 
    // EDIT: As per comments changed to turn the button into a Start/Stop button. 
    //  When the button is pressed and the timer is stopped, the timer is started, 
    //  otherwise it is started. 

    // Stop the timer if it runs already 
    if (timer.Enabled) 
    { 
     timer.Stop(); 
    } 

    // Start the timer if it was stopped 
    else 
    { 
     // Make the timer start right away 
     currentImageIndex = 0; 
     timer.Interval = 1; 

     // Start the timer 
     timer.Start(); 
    } 
} 

內計時器事件,使用此代碼:

private void timer_Tick(object sender, EventArgs e) 
{  
    timer.Stop(); 
    try 
    { 
     timer.Interval = 5000; // Next time, wait 5 secs 

     // Set the image and select next picture 
     button1.BackgroundImage = (Image)Properties.Resources.ResourceManager.GetObject(arr1[currentImageIndex]); 
     currentImageIndex++; 
    } 
    finally 
    { 
     // Only start the timer if we have more images to show! 
     if (currentImageIndex < arr1.Length) 
      timer.Start(); 
    } 
} 
+1

這可以工作,它可能在這裏可以,但DoEvents()可能會有一些危險的副作用。 –

+0

按下按鈕時使用計時器的正確代碼是什麼? – marios

+0

@marios在編寫評論時編輯答案。請參閱代碼。 –

0

要做到這一點的最佳方法是與定時器控制結合使用。將計時器的時間間隔設置爲1秒,但將其保持禁用狀態。然後,按下按鈕代碼只是啓用計時器。

public partial class MyForm : Form 
{ 
    private int ImagePosition = 0; 
    private string[] arr1 = new string[] { "water", "eat", "bath", "tv", "park", "sleep" }; 

    private void button1_Click(object sender, EventArgs e) 
    { 
     ImagePosition = 0; 
     RotateImage(); 
     Timer1.Start();  
    } 

    private void RotateImage() 
    { 
     button1.BackgroundImage = 
     (Image)Properties.Resources.ResourceManager.GetObject(arr1[ImagePosition]); 
     new SoundPlayer(Properties.Resources.nero).Play(); 
     ImagePosition++; 
    } 

    private void timer1_Tick(object sender, EventArgs e) 
    { 
     if (ImagePosition > 5) 
     { 
      timer1.Enabled = false; 
      return; 
     } 

     RotateImage(); 
    } 
} 
+0

此代碼的負面影響:計時器將在顯示第一張圖像之前等待一秒鐘。另外,我真的很想注意到,基於語法約定,變量名稱以C#中的小寫字母開始:-) –

+1

修復了延遲問題 –

+0

:-D很好的解決方案。 –