2017-02-22 38 views
2

我正在嘗試編寫一個簡單的程序(c#),它讀取一組zip文件以搜索某些特定文件。進度條不按最大尺寸進度

我實現了這個使用winform和後臺工作,但我有一些麻煩了解如何配置進度條根據我解析文件的數量動態進步。

例如在目錄A中我有400個zip文件,所以我希望進度條的「大小」爲400個單位,因此打開的每個文件都會將進度條增加1.在目錄B中,我只有4個zip文件,所以我需要4塊在進度欄

我試圖做下面的代碼,只是爲了測試進度條 我設置最大值爲20(代表20個zip文件),並在一個循環遞增1進度酒吧

 private void button_SearchZip_Click(object sender, EventArgs e) 
    { 
     if(!backgroundWorker_SearchZip.IsBusy) 
     { 
      SearchZipArgs args = new SearchZipArgs 
      { 
       sourceDirectory = this.textBox_SrcDir.Text 
      }; 

      backgroundWorker_SearchZip.RunWorkerAsync(args); 
      this.button_SearchZip.Enabled = false; 
     } 
     else 
     { 
      MessageBox.Show(@"Search already in process. please try again later"); 
     } 
    } 

    private void backgroundWorker_SearchZip_DoWork(object sender, DoWorkEventArgs e) 
    { 

      this.progressBar_SearchZip.Style = ProgressBarStyle.Blocks; 
      //this.progressBar_SearchZip.Step = 1; 
      this.progressBar_SearchZip.Minimum = 0; 
      this.progressBar_SearchZip.Maximum = 20; 
      for(int i = 0; i < 20; i++) 
      { 
       backgroundWorker_SearchZip.ReportProgress(i); 
       Thread.Sleep(300); 
      } 
    } 

    public MainForm() 
    { 
     InitializeComponent(); 
     this.backgroundWorker_SearchZip.WorkerReportsProgress = true; 
     this.backgroundWorker_SearchZip.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker_SearchZip_DoWork); 
     this.backgroundWorker_SearchZip.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker_SearchZip_ProgressChanged); 
     this.backgroundWorker_SearchZip.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker_SearchZip_RunWorkerCompleted); 
    } 

    private void backgroundWorker_SearchZip_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     progressBar_SearchZip.Value = e.ProgressPercentage; 
    } 

,但是這是我的進度條得到:

Progress bar screenshot when work is done

出於某種原因,如果取消註釋:

this.progressBar_SearchZip.Step = 1; 

進度條完全不

工作的任何幫助將是不錯:)

編輯: 發現問題!我試圖從後臺線程中更改進度條,並且出現錯誤「跨線程操作無效:控制'progressBar Search Zip'從修改此錯誤後創建的線程以外的線程訪問」 在此線程的幫助下:Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on)問題已解決

+0

backgroundWorker.ProgressChanged事件在哪裏? – A3006

+0

@ A3006忘了添加它。我編輯了問題 – Dardar

回答

1

Step屬性用於調用PerformStep方法時。

要設置進度條的當前位置,你可以使用Increment功能是這樣的:

progressBar.Increment(1); 

或將其值設置如下:

progressBar.Value = yourValue; 
+0

@S。 Dav - 據我所知 - 我們是否需要在ProgressChanged中編寫這些行?我認爲這是從ReportProgress調用的? – A3006

+0

您可能是對的,但我們在問題中看不到ReportProgress函數。 –

1

您需要添加

backgroundWorker_SearchZip.ProgressChanged += this.OnProgressChanged; 

進入您的初始化函數(例如)

然後添加

private void OnProgressChanged(object sender, ProgressChangedEventArgs e) { 
    this.progressBar_SearchZip.Increment(1); 
} 
+0

按照您的建議在按鈕單擊事件中訂閱「ProgressChanged」事件真的是一個好主意嗎?這應該最好在'Form_Load'或其他初始化方法上完成。 –

+0

好點,我誤解了這個問題,並認爲我看到它在點擊事件中被初始化。我會做一個編輯 –

+0

@ S.Dav忘了添加ProgressChanged代碼。我編輯了這個問題 – Dardar

0

此代碼的工作對我來說:

this.progress_bar.Properties.Minimum = 0; 
this.progress_bar.Properties.Maximum = datatable.Rows.Count; 

foreach (DataRow row in datatable.Rows)  { 

    // operation that you need to do  

    this.progress_bar.Increment(1); 
    this.progress_bar.Update(); 
} 

好運

+0

所以如果你得到10行或1000行 - 在這兩種情況下,進度條一直填充到最後? – Dardar

+0

是的,每次迭代在foreach中將進度條值增加1,並更新進度條狀態.... 該示例代碼在從數據表導入行並執行一系列操作的項目中可用與他們一起檢查。 – raBinn