2013-05-01 2 views
0

J'écris une application C# pour télécharger et télécharger un fichier. Le téléchargement utilise l'objet WebClient et sa méthode DownloadAsycDownload. Le téléchargement fonctionne correctement pour plusieurs fichiers. Il télécharge autant de fichiers que je veux.C# Plusieurs barres de progression pour plusieurs téléchargements de fichiers

Mon problème est que je ne suis pas en mesure d'afficher la progression de tous les fichiers dans différentes barres de progression qui sont ajoutées dynamiquement au formulaire flowlayout control.

Voici mon code:

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;     
} 

Répondre

1

Vous utilisez un compte pour indexer dans les barres de progression, mais une fois que l'on est complet - vous retirez le dernier, où vous devriez vraiment supprimer celui qui est associé avec le fichier.

Je suggère, dans ce cas, en utilisant un Dictionary<WebClient, ProgressBar> (pourrait ne pas être WebCliet - devrait être le type de sender dans les événements).

... 
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(); 

Ensuite, vous pouvez supprimer countBar tout à fait, et que les nouvelles méthodes:

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

Merci, c'était très utile. – Habtamu

+0

Si cela vous a entièrement aidé, marquez comme réponse acceptée. Sinon, laissez-moi savoir ce qui manque. – SimpleVar

+0

J'essaie d'ajouter les composants d'une autre classe. Ne pas obtenir la barre de progression ajoutée au formulaire lors de l'exécution. Ces méthodes que j'ai postées sont dans une autre classe. – Habtamu

1

Je voudrais utiliser quelque chose comme ça avec lambdas, un peu plus concis, pas besoin dans le dictionnaire:

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); 
Questions connexes