2017-01-12 75 views
-2

在C#即時試圖做一個小遊戲類型的程序,即時通訊嘗試使一個加載欄,使用進度欄和文本使用標籤,例如進度欄1 - 25,我想在標籤的文本更新而酒吧,下面有一個例子:
C#標籤文本不更新,而進度條值是

private void StartLoading_Click(object sender, EventArgs e) 
    { 
     MainProgressBar.Maximum = 25; 
     int P = 0; 
     while (P < 25) 
     { 
      // Delay 
      System.Threading.Thread.Sleep(130); 
      // Increase Progress 
      P++; 
      // Set Progress Bar Value 
      MainProgressBar.Value = P; 
      // Set Text Above Progress Bar 
      LoadingText.Text = P + "/25"; 
     } 
    } 

詩篇。我不希望一些巨大的代碼,我希望它是簡單的這樣

+0

嘗試搜索,不要屏蔽UI線程,使用背景工作。是的,這是「龐大的代碼」,但它是必要的。 – CodeCaster

+0

在GUI線程中更新控件時,大多數控件都不會處理消息(因爲它們僅在執行結束後才收到消息)。你應該使用工作線程。不推薦第二種方法(處理消息)。進度條具有不同的處理系統,因此它可以像預期的那樣工作,但它大多是圖形控件中的一個例外。 – Julo

+0

在視圖模型中創建兩個屬性,一個用於最大值,另一個用於當前值,然後綁定到視圖中的兩個值。 – LordWilmore

回答

1

的現有技術是這個片段爲您:

private void StartLoading_Click(object sender, EventArgs e) 
    { 
     const int max = 25; 
     var progressHandler = new Progress<int>(value=>{ 
      LoadingText.Text = value + "/" + max; 
      MainProgressBar.Value = value; 
     }); 

     var progress = progressHandler as IProgress<int>; 
     await Task.Run(() => 
     { 
      int P = 0; 
      while (P < 25) 
      { 
       Thread.Sleep(130); 
       progress?.Report(++P); 
      } 
     }  
    } 

這種處理您的長期運行的任務(睡在這種情況下),在一個獨立的Thread並通過Progress-Class重用該值。這樣,您的GUI將按照建議在GUI線程中更新,您將相應地獲得更新。此外,不建議使用Application.DoEvents();,因爲您必須知道很多pitfalls

+0

它說什麼_Application.DoEvents()這僅僅是爲了backwardcompatibilty而不應該被use_?不[這裏](https://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents(v = vs.110).aspx)至少:) – Pikoh

+0

@Pikoh我更新了我的回答並糾正它。它來自VB 5.X,但在.Net中似乎也沒問題。有很多你必須知道和避免的陷阱:http://stackoverflow.com/questions/5181777/use-of-application-doevents – Sebi

+0

這樣更好。無論如何,我還會推薦閱讀[這個鏈接](https://blog.codinghorror.com/is-doevents-evil/),它基本上講述了我在我的評論中已經講過的內容:對於簡單的情況在OP示例中,使用'DoEvents()'是完全正確的。 – Pikoh