2014-06-20 57 views
1

我在form1中有一個progressBar1和BackgroundWorker,當我點擊按鈕來創建avi文件時,我希望它根據avi文件的創建進度來報告progressBar。如何在使用BackgroundWorker時向ProgressBar報告?

這是我創建的avi文件類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using AviFile; 
using System.Drawing; 
using System.IO; 

namespace WindowsFormsApplication1 
{ 
    class CreateAvi 
    { 
     public static void AviMovie(FileInfo[] FileNames) 
     { 
      Bitmap bitmap = (Bitmap)Image.FromFile(FileNames[0].FullName); 
      AviManager aviManager = 
       new AviManager(@"c:\temp\new.avi", false); 
      VideoStream aviStream = 
       aviManager.AddVideoStream(false, 25, bitmap); 
      int count = 0; 
      for (int n = 1; n < FileNames.Length; n++) 
      { 
       if (FileNames[n].Length > 0) 
       { 
        bitmap = 
         (Bitmap)Bitmap.FromFile(FileNames[n].FullName); 
        aviStream.AddFrame(bitmap); 
        bitmap.Dispose(); 
        count++; 
       } 
      } 
      aviManager.Close(); 
     } 
    } 
} 

在Form1:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      CreateAvi.AviMovie(allfiles); 
     } 

進展:

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 

     } 

完成:

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 

     } 

這是我在Form1做:

這是CreateAvi類中的方法,我改變它,所以它也將得到form1的BackgroundWorker的(稱爲變量bgw1):

public static void AviMovie(FileInfo[] FileNames,BackgroundWorker bgw1) 
     { 
      Bitmap bitmap = (Bitmap)Image.FromFile(FileNames[0].FullName); 
      AviManager aviManager = 
       new AviManager(@"c:\temp\new.avi", false); 
      VideoStream aviStream = 
       aviManager.AddVideoStream(false, 25, bitmap); 
      int count = 0; 
      for (int n = 0; n < FileNames.Length; n++) 
      { 
       if (FileNames[n].Length > 0) 
       { 
        bitmap = 
         (Bitmap)Bitmap.FromFile(FileNames[n].FullName); 
        aviStream.AddFrame(bitmap); 
        bitmap.Dispose(); 
        count++; 
        int pctDone = count * 100/FileNames.Length; 
        bgw1.ReportProgress(pctDone); 
       } 
      } 
      aviManager.Close(); 
     } 

然後在form1我在dowork事件中改變,所以它會得到backgroundworker1:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      CreateAvi.AviMovie(allfiles,backgroundWorker1); 
     } 

     private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      progressBar1.Value = e.ProgressPercentage; 
      label9.Text = getallfiles[e.ProgressPercentage].FullName; 
     } 

所以progressBar真的到了100%的最後。然而,在label19我只看到,直到文件000101.jpg在這idrectory有167文件的最後一個000167.jpg

getallfiles是FileInfo[] 而在Form1構造我所做的:

var directory = new DirectoryInfo(mainDirectory); 
getallfiles = directory.GetFiles("*.jpg"); 

我看到getallfiles包含167個文件。我如何向標籤報告正在處理的文件名?

+0

您可以在form1上創建一個Method,更新ProgressBar的值(可能是自我激勵)。然後eigther訪問它或重構CreateAviClass,以便它接受該方法的委託,您可以從您的非靜態AviMovie方法調用該方法。 *編輯:*或者只是使用DGobbs建議的Backgroundworker的ReportProgress方法 – MrPaulch

+0

看看我的questin,請更新它與我試圖報告文件名稱到一個labe – user3756594

+0

編輯我的問題之前,我沒有顯示我改變了什麼createavi類我改變了方法,所以它會得到backgroundworker1。 – user3756594

回答

1

ReportProgress需要在那裏進步實際上發生於從方法調用:

public static void AviMovie(FileInfo[] FileNames,BackgroundWorker bgw1) 
{ 
    Bitmap bitmap = (Bitmap)Image.FromFile(FileNames[0].FullName); 
    AviManager aviManager =new AviManager(@"c:\temp\new.avi", false); 
    VideoStream aviStream =aviManager.AddVideoStream(false, 25, bitmap); 
    int count = 0; 
    for (int n = 0; n < FileNames.Length; n++) 
    { 
     if (FileNames[n].Length > 0) 
     { 
     bitmap =(Bitmap)Bitmap.FromFile(FileNames[n].FullName); 
     aviStream.AddFrame(bitmap); 
     bitmap.Dispose(); 
     count++; 
     int pctDone = count * 100/FileNames.Length; 
     bgw1.ReportProgress(pctDone); 
     } 
    } 
    aviManager.Close(); 
} 

此外,你的循環需要在0開始 - 你跳過第一個元素FileNames

編輯:在你的後臺工作的ProgressChanged事件,您不能使用e.ProgressPercentage您的數組索引,你必須從百分比落後工作取得索引:

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { 
    progressBar1.Value = e.ProgressPercentage; 
    int fileIndex = e.ProgressPercentage * FileNames.Length/100; 
    label9.Text = getallfiles[fileIndex].FullName; 
} 
+0

如何爲標籤分配當前正在處理的每個文件的名稱?我嘗試在backgroundworker progress事件中的form1中進行設置:label9.Text = allfiles [e.ProgressPercentage] .FullName;但是當進度條達到100%時,我只能看到文件000101.jpg,並且目錄中的最後一個文件是000167.jpg – user3756594

+0

C-Pound看看我的問題,請用我試過的報告文件名更新爲標籤。 – user3756594

+0

我還看到CreateAvi類中的FileNames也包含167個文件。那麼爲什麼我在進度報告中只看到了101個文件呢? – user3756594

2

通過使用ReportProgress

private void DoWork() 
{ 
    // Calculate percent done 
    backgroundWorker.ReportProgress(percentageComplete); 
} 

這將觸發你有,你可以安全地更新UI的backgroundWorker1_ProgressChanged事件。

+0

DGibbs看着我的問題更新到目前爲止我所做的,但它不工作。 – user3756594

+0

你試過的方式只有在你完成了'AviMovie'後才報告你的進度。 – MrPaulch

+1

好吧,一開始你沒有計算一個百分比值......你還需要從'AviMovie'裏面報告進度。操作完成後,您正在報告它。 – DGibbs

0

你應該把AviMovie()到bgw_DoWork(),身體和這些行添加到所述主體的頂部:

FileInfo fileInfo = (FileInfo[])e.Argument; 
int steps = fileInfo.Length; 
BackgroundWorker bgw = (BackgroundWorker)sender; 

在的結尾for循環添加這一行:

bgw.ReportProgress((int)(100/steps) * n, null); 

,並開始與這個工人:

bgw.RunWorkerAsync(FileNames); //FileNames is of course the array 

還有其他的方法來做到這一點,當然,不過這可能是我會做什麼。

相關問題