2009-05-21 13 views
1

私は非常にプログラミングに新しいし、これまでかなりうまくいっています。しかし、プログレスバーはまだ私を混乱させる。残念ながら、ウェブは私に何かを得るために多くの異なる例があります。何人かはバックグラウンドワーカーを使っていると言っている人もいますし、そうでない人もいます。 1つのフォルダから別のフォルダにファイルをコピーするときにプログレスバーを表示することになっています。どんな助けもありがとうございます。プログレスバーのヘルプ

ありがとうございました。

 private void btnCopyFiles_Click(object sender, EventArgs e) 
    { 
     string folder1 = @"c:\folder1\"; 
     string folder2 = @"c:\folder2\"; 

     DirectoryInfo di = new DirectoryInfo(folder1); 
     FileInfo[] filelist = di.GetFiles("*.*"); 
     int count = di.GetFiles("*.*").Length; 

     this.progressBar1 = new System.Windows.Forms.ProgressBar(); 
     progressBar1.Maximum = count; 
     progressBar1.Minimum = 0; 
     progressBar1.Step = 1; 

     foreach (FileInfo file in filelist) 
     { 
      try 
      { 
       this.Cursor = Cursors.WaitCursor; 
       File.Copy(folder1 + @"\" + file.Name, folder2 + @"\" + file.Name, true); 
       progressBar1.PerformStep(); 
       this.Cursor = Cursors.Default; 
      } 
      catch (Exception error) 
      { 
       MessageBox.Show("Error: " + error); 
      } 
     } 
    } 

答えて

4

私はあなたがVisual Studioを使用しており、ProgressBarコントロールをフォームにドラッグして追加したと仮定しています。これが正しい場合は、次の行が問題の可能性があります。

this.progressBar1 = new System.Windows.Forms.ProgressBar(); 

コントロールを再作成すると、フォームへのリンクが失われています。その行を削除またはコメントして、もう一度試してみてください。

+0

ありがとうございます!それは動作します。道のりのどこかで私はそこに持っていなければならないと思った。しかし、素晴らしい作品。再度、感謝します。 – JimDel

+1

あなたは私の答えを受け入れ、それを受け入れなかった理由はありますか? – ichiban

+0

ああ。良い目。私はそれを見ませんでした。 – Crispy

0

あなたはprogressbar1.Increment(x)を試しましたか?xは転送されたファイルの数ですか?

+0

コードには既にprogressBar1.PerformStep()があります。 – ichiban

2

全体的に問題は、コードが実行され続けて、必要に応じてフォームを再描画できないことです。あなたの最善かつ最速のルートは、実際にあなたの操作を実行するために、そのイベントを使用して進捗状況を更新するために、BackgroundWorkerを使用することです。これを行うと、プログレスバーの更新はUIスレッドで行われ、UIが更新されると、ファイル操作は舞台裏で続けられます。

+0

ichibansの答えは私の問題を解決しました。しかし、私はバックグラウンド労働者のやり方についてさらに詳しく見ていきます。ありがとう:) – JimDel

1

ユーザーインターフェイスで進行状況バーを更新するには、何かを処理しているプロセスが別のスレッドで実行されている必要があります(そうしないとUIスレッドがブロックされ、UIは更新されません)。これを行うには、BackgroundWorkerが適しています。

バックグラウンドワーカーのDoWorkイベントでファイルコピーループを実行し、BackgroundWorker.ReportProgressメソッドを呼び出して、進捗状況を報告してください。 ProgressChangedイベントのイベントハンドラでは、ProgressBarコントロールの値を設定できます。 BackgroundWorkerコンポーネントのRunWorkerAsyncメソッドを呼び出すと、プロセスが開始されます。

1

プログラミングの初心者ですから、これで始まります。

これは、アプリケーションが現在のために働いてもらう必要があります

progressBar1.PerformStep(); 

Application.DoEvents(); 

を追加します。最終的には、コピープロセスをスレッド/バックグラウンドワーカーに移動したいと思うでしょう。しかし、あなたの能力を知らずに、Application.DoEvents()はおそらく最も簡単な修正ですが、推奨される修正はありません。

2

まず、DoWorkEventArgsに渡されるBackgroundWorkerの引数を保持する構造体を作成します。

public struct CopyStruct 
{ 
    public string sourceDir; 
    public string destDir; 
} 

そこで、このような何か:

private void btnCopyFiles_Click(object sender, EventArgs e) 
{ 
    InitializeBackgroundWorker(); 

    CopyStruct copyStruct = new CopyStruct 
    { 
     sourceDir = @"C:\folder1\", 
     destDir = @"C:\folder2\" 
    }; 

    backgroundWorker.RunWorkerAsync(copyStruct); 
} 

private void InitializeBackgroundWorker() 
{ 
    backgroundWorker.WorkerReportsProgress = true; 
    backgroundWorker.DoWork += backgroundWorker_DoWork; 
    backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted; 
    backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged; 
} 

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

private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    // do something when finished 
} 

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    BackgroundWorker worker = (BackgroundWorker) sender; 
    CopyStruct copyStruct = (CopyStruct) e.Argument; 

    DirectoryInfo di = new DirectoryInfo(copyStruct.sourceDir); 
    FileInfo[] filelist = di.GetFiles("*.*"); 

    int numFiles = filelist.Length; 

    for (int i = 0; i < numFiles; i++) 
    { 
     FileInfo file = filelist[i]; 

     File.Copy(Path.Combine(copyStruct.sourceDir, file.Name), Path.Combine(copyStruct.destDir, file.Name), true); 

     // This line updates the progress bar 
     worker.ReportProgress((int) ((float) i/numFiles*100)); 
    } 
} 

をあなたはそれを追加する必要がありますので、これは、ほとんどエラーチェックが含まれていないが、それは私のシステム上でいくつかのテストディレクトリで動作します。

+0

あなたの部分に多くの仕事があります!どうもありがとうございます!今私はいくつか私の前に実験している。 – JimDel

+0

ありがとうございます。あなたがあなたのために働くものなら、あなたはBackgroundWorkerは必要ありません。私は「3209/9000(35%)」のようなもので更新されたラベルも持っていたので、私は1つだけ必要でした。 BackgroundWorkerがなければ、ラベルは決して更新されませんが、backgroundWorker_ProgressChanged関数でうまく動作します。 –