2013-10-13 96 views
0

如果你能想象這是一個加載條:UI元素沒有更新

for (int i = 0; i < r.Width/2; i++) //Fills half the loading bar. 
{   
    Rectangle rect = can.Children[3] as Rectangle; //getting the 3rd element of my Canvas 
    if (rect != null) 
    { 
     rect.Fill = brush; 
     rect.Width = i; 
     Thread.Sleep(50); 
    } 
} 

因此,應用程序將不會顯示增加額外的矩形的進展。相反,它只是凍結線程休眠的總時間,當for循環結束時它會顯示整個線條。

這是爲什麼?

我知道有一個內置的加載欄,但這只是我遇到的問題的一個例子。

+0

這種情況發生的原因是您在UI線程中運行。 – Jviaches

+0

如果這是在你的UI線程中完成的,thread.sleep會導致你的UI凍結。嘗試使用後臺工作者。 –

+0

請參閱BackgroundWorker ReportsProgress。在您當前的代碼中,直到該循環完成後纔會更新UI。 – Paparazzi

回答

2

我建議你開始閱讀關於線程,後臺工作人員,調度員。除非您向解決方案添加線程,否則整個應用程序將在UI線程的幫助下運行。

如果您有可以連續執行的任務,則無需實現線程或後臺工作程序。就你而言,你正在嘗試做2個任務。

  1. 更新的矩形,並畫出其上的窗口
  2. 睡眠線程50毫秒

當UI線程執行了Thread.Sleep(50);它不能繪製(在矩形中顯示進度)。這就是您的應用程序凍結數秒並在您看到任何進度之前完成的原因。我將試着用2個例子來解釋這個。

舉例:1 添加與IsIndeterminate="True"Button1進度條到您的演示應用程序。

<ProgressBar IsIndeterminate="True" Height="20" Name="progressBar1" Width="177" Visibility="Hidden" /> 

在後面的代碼,

private void button1_Click(object sender, RoutedEventArgs e) 
     { 
      progressBar1.Visibility = Visibility.Visible; 
      Thread.Sleep(5000); 
      progressBar1.Visibility = Visibility.Hidden; 
     } 

如果你運行這段代碼,你將不會看到任何進度條的代碼是越來越串行執行。要確保進度條正常顯示並隱藏,請執行以下更改。

例2:

private void button1_Click(object sender, RoutedEventArgs e) 
     { 
      progressBar1.Visibility = Visibility.Visible; 
      Thread t = new Thread(DoMyWork); 
      t.Start(); 
     } 

    private void DoMyWork() 
       { 
        Thread.Sleep(5000); 
        //hide the progress bar after completing your work 
        this.Dispatcher.Invoke((Action)delegate { progressBar1.Visibility = Visibility.Hidden; }); 
       } 

enter image description here

運行這段代碼,你可以看到,雖然UI線程更新進度,創造了新的線程執行DoMyWork功能。

您需要this.Dispatcher.Invoke((Action)delegate作爲progressBar1在UI線程中創建,並且您不能在另一個線程中訪問它。即線程t =新線程(..)

P.S.-這是編碼方式的骯髒。這只是給出一個想法,如何在OP的情況下工作。