0

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

我的问题是我无法在动态添加到表单的不同进度条中显示所有文件的进度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;                
}
4

2 回答 2

1

您正在使用计数来索引进度条,但是一旦完成 - 您删除最后一个,您确实应该删除与文件关联的那个。

我建议,在这种情况下,使用 a 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;                
}
于 2013-05-01T07:07:25.523 回答
1

我会在 lambdas 中使用这样的东西,更简洁一点,字典中不需要:

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);
于 2014-11-02T19:48:25.210 回答