2013-05-01 190 views
0

我正在编写一个用于上传和下载文件的C#应用​​程序。下载使用WebClient对象及其DownloadAsycDownload方法。下载适用于多个文件。它下载尽可能多的文件,我想要的。C#多个进度条用于多个文件下载

我的问题是我无法显示所有文件在不同进度条上的动态添加到窗体的flowlayout control的进度。

这里是我的代码:

public ProgressBar[] bar; 
public int countBar=0; 

... 

    bar[countBar] = new ProgressBar(); 
    flowLayoutPanel1.Controls.Add(bar[countBar]); 
    countBar++; 

    request.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownoadInProgress); 
    request.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCompleted); 
    request.DownloadFileAsync(new Uri(this.uri), localPath); 

    byte[] fileData = request.DownloadData(this.uri); 
    FileStream file = File.Create(localPath); 
    file.Write(fileData, 0, fileData.Length); 
    file.Close(); 
} 

public void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 
{ 
    flowLayoutPanel1.Controls.Remove(bar[countBar]); 
    countBar--; 
    MessageBox.Show("Download Completed"); 
} 

public void DownoadInProgress(object sender, DownloadProgressChangedEventArgs e) 
{ 
    bar[countBar].Maximum = total_bytes; 
    bar[countBar].Value = (int)e.BytesReceived;     
} 

回答

1

您使用的计数索引到进度条,但一旦一个完成 - 删除最后一个,你真的应该删除相关联的一个与文件。

我建议,在这种情况下,使用Dictionary<WebClient, ProgressBar>(可能不是WebCliet - 应该是事件中的sender的类型)。

... 
var progBar = new ProgressBar(); 
progBar.Maximum = 100; 
flowLayoutPanel1.Controls.Add(progBar); 

request.DownloadProgressChanged += DownoadInProgress; 
request.DownloadFileCompleted += DownloadFileCompleted; 
request.DownloadFileAsync(new Uri(this.uri), localPath); 

dic.Add(request, progBar); 

// You shouldn't download the file synchronously as well! 
// You're already downloading it asynchronously. 

// byte[] fileData = request.DownloadData(this.uri); 
// FileStream file = File.Create(localPath); 
// file.Write(fileData, 0, fileData.Length); 
// file.Close(); 

然后,您可以完全删除countBar,并有新的方法:

public void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 
{ 
    // Can remove (WebClient) cast, if dictionary is <object, ProgressBar> 
    var request = (WebClient)sender; 
    flowLayoutPanel1.Controls.Remove(dic[request]); 
    dic.Remove(request); 
    MessageBox.Show("Download Completed"); 
} 

public void DownoadInProgress(object sender, DownloadProgressChangedEventArgs e) 
{ 
    var progBar = dic[(WebClient)sender]; 
    progBar.Value = e.ProgressPercentage;     
} 
+0

谢谢,这真的很有帮助。 – Habtamu 2013-05-02 12:10:38

+0

如果这完全帮助你,请将其标记为已接受的答案。否则,让我知道缺少的东西。 – SimpleVar 2013-05-02 13:55:44

+0

我想从另一个类中添加组件。在运行时无法将进度条添加到表单中。我发布的这些方法在另一个类中。 – Habtamu 2013-05-02 14:41:03

1

我会用这样的事情与lambda表达式,有点更简洁,没有必要在词典:

var webClient = new WebClient(); 

var pb = new ProgressBar(); 
pb.Maximum = 100; 
flowLayoutPanel1.Controls.Add(pb); 

webClient.DownloadProgressChanged += (o, args) => 
{ 
    pb.Value = args.ProgressPercentage; 
}; 

webClient.DownloadFileCompleted += (o, args) => 
{ 
    flowLayoutPanel1.Controls.Remove(pb); 
}; 

webClient.DownloadFileAsync(new Uri(this.uri), localPath);