2013-09-24 122 views
-3

我是C#.NET的新手。我試圖用我的主界面中的一個Progess欄創建一個窗體來顯示進度。我使用BackgroundWorker來調用它。我能夠顯示進度對話框,但不能更新進度欄值。請找到下面的代碼。無法使用BackgroundWorker更新單獨表單中的進度條c#.net表單

主界面:

namespace GC 
{ 
    public partial class MainUI : Form 
    { 
     private ProgressBar oProgressBar; 
     public MainUI() 
     { 
      InitializeComponent(); 

     } 

     private void runButton_Click(object sender, EventArgs e) 
     { 
      oProgressBar = new ProgressBar(); 

      backgroundWorker1 = new BackgroundWorker(); 

      backgroundWorker1.WorkerReportsProgress = true; 

      backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); 

      backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged); 

      backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted); 

      backgroundWorker1.RunWorkerAsync(); 

      oProgressBar.ShowDialog(); 



     } 


     private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      //some work here 

      for (int i = 0; i < 20; i++) 
       backgroundWorker1.ReportProgress(i); 


     } 


     private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 

      oProgressBar.Close(); 
     } 
     void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      oProgressBar.progressBar1.Value = e.ProgressPercentage; 

     } 

    } 

} 

進度條UI這種形式包含一個進度條

namespace GC 
{ 
    public partial class ProgressBar : Form 
    { 
     public ProgressBar() 
     { 

      InitializeComponent(); 

     } 


     } 
} 
+0

會發生什麼?酒吧是否滿20%? – musefan

+0

可能與oProgressBar.ShowDialog();它停止,直到你關閉oProgressBar。但我不確定。 – asharajay

+0

發生了什麼......? – Jonesopolis

回答

-3

你需要調用的形式線程上的更新?

void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    if(InvokeRequired) 
    { 
     Invoke(new EventHandler<ProgressChangedEvent>(backgroundWorker1_ProgressChanged), sender, e); 
    } 
    else 
     oProgressBar.progressBar1.Value = e.ProgressPercentage; 

} 
+1

這個答案是不正確的,當以這種方式使用後臺工作器時不需要調用 – musefan

+0

真的嗎?也許不是在最新的.NET中,而是在早期版本中,沒有使用Invoke,你會得到一個交叉線程異常(即您只能從創建它的線程更新控件) – Neil

+0

「ProgressChanged」事件在啓動後臺工作器的同一線程上運行,後者通常是主UI線程(當然似乎是在這個問題中)。所以不需要調用,如果你有後臺工作人員調用後臺工作人員,它可能會變得混亂......但不知道你爲什麼要這麼做無論如何 – musefan

0

看起來對我很好,

我覺得你的問題是更象:

  • 車窗緊閉之前,你看到它填補因爲:

    oProgressBar.Close( );

  • 如所述musefan您的欄填滿只有20%,這是正常的,因爲的:

    對(INT I = 0;我< 20; i ++在) backgroundWorker1.ReportProgress(ⅰ);

如果你想看到它完全填滿,使用for循環,以100:的for(int i = 0;我< 100;我++)

+0

但是即使高達20%的填充也沒有發生:( –

+0

您是否嘗試刪除oProgressBar.Close();? 奇怪,因爲我複製了您的代碼,並且它對我很好用 也許我錯過了一些關於您的backgroundWorker1的地方你是否聲明它?對我來說,它應該是你的MainUI表單的一個字段 – Ouarzy

1

根據您所提供的信息,有一對夫婦的事情,可能是問題,但要看是什麼行爲,你遇到:

方案1:進度條的形式看到任何更新

問題前關閉是你關閉了m幾乎在進度條更新後立即生效。這將發生得如此之快,以至於您將沒有時間查看進度欄更新。

方案2:的進度條的形式保持打開狀態,而酒吧永遠不會更新

這對我來說將表明,你有你的「做工作」的代碼錯誤,導致無法有史以來ReportProgress功能被稱爲。爲了檢查這一點,我建議使用調試器單步執行代碼。


你應該做的

更新進度條在for循環中,如果沒有意義就像你在你的例子。你的例子會導致進度條立即跳轉到20%並停留在那裏。在你的工作過程的每個「步驟」之後,你應該增加進度條。此外,重要的是,您的任務實際上需要一些時間來執行(更改一秒)以給它時間來顯示某些內容。

例如,如果您的任務正在從數據庫中讀取記錄,那麼您可能會在每行讀取後報告進度。我也建議你把它全部包裝起來,並提醒任何錯誤(只是爲了知道,所以你可以調試你的問題)...

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     //Do Stuff: e.g. read from DB 
     var tasks = GetTasks(); 

     int i = 0; 
     double percentageIncrease = 100d/tasks.Count(); 
     foreach(var task in tasks) 
     { 
      //do something for this task 
      backgroundWorker1.ReportProgress((int)(percentageIncrease * i)); 
      i++; 
     } 
    } 
    catch(Exception ex) 
    { 
     MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK); 
    } 
}