C#:foreach循环中的进度更改事件不知道如何使用进度条显示进度

时间:2016-11-06 15:22:44

标签: c# foreach progress-bar progress

目前我正在C#中创建一个视频下载器,因为我允许用户一次选择多个视频进行下载,所选视频将转到列表视图控件。我想显示每次下载的进度。这是我开始下载的代码:

 listView1.Invoke(new MethodInvoker(delegate ()
            {
                foreach (ListViewItem item in listView1.SelectedItems)
                {
                    try
                    {
                        listViewItems = listView1.Items.Count;
                        string path = Properties.Settings.Default.outputFolder;
                        IEnumerable<VideoInfo> videos = DownloadUrlResolver.GetDownloadUrls(item.Text);
                        VideoInfo video = videos.First(p => p.VideoType == VideoType.Mp4);
                        if (video.RequiresDecryption)
                            DownloadUrlResolver.DecryptDownloadUrl(video);
                        title = video.Title;
                        foreach (char c in invalid)
                        {
                            title = title.Replace(c.ToString(), "");
                        }
                        VideoDownloader downloader = new VideoDownloader(video, Path.Combine(path + "\\", title + video.VideoExtension));
                        downloader.DownloadProgressChanged += Downloader_DownloadProgressChanged;
                        downloader.DownloadFinished += Downloader_DownloadFinished;
                        Thread thread = new Thread(() =>
                        {
                            downloader.Execute();
                        })
                        { IsBackground = true };

                        thread.Start();
                    }
                    catch (Exception web)
                    {
                        DialogResult dlg = new DialogResult();
                        messageBox msb = new messageBox();
                        msb.labelText = "Video no longer available";
                        msb.btnText = "Ok";
                        dlg = msb.ShowDialog();
                        if(dlg == DialogResult.OK)
                        {
                            msb.Close();
                        }
                 }
                }

这是进步改变事件:

private void Downloader_DownloadProgressChanged(object sender, ProgressEventArgs e)
    {
        flowLayoutPanel1.Invoke(new MethodInvoker(delegate
        {
            ProgressBar pb = new ProgressBar();
            pb.Value = (int)e.ProgressPercentage;
            flowLayoutPanel1.Controls.Add(pb);
        }));

    }

而不是为每个项目进度条创建它创建了很多进度条,这些进度条也没有显示进度。

我是c#的新手,所以需要帮助。

2 个答案:

答案 0 :(得分:1)

我发现代码有点难以在没有实际运行的情况下遵循,但我建议将问题分成两部分。首先,确保DownloadProgressChanged事件正常工作,这意味着每次进度发生变化时都会触发,并且e.ProgressPercentage实际上确实有值。每次DownloadProgressChanged触发时,您都不应该添加新的进度条。其次,获取一些简单的ProgressBar代码,无论是担心整个项目列表,还是进行视频下载。

将问题分解为可管理的部分,然后从那里构建它。

答案 1 :(得分:1)

每次活动发生时,您都在创建一个进度条。您需要在流程开始之前创建一个,并且只更新它在事件上的值。 sp ProgressBar pb = new ProgressBar();flowLayoutPanel1.Controls.Add(pb);不属于此事件。

<强>更新

我现在看到你想为每次下载添加一个进度条。

您必须将2行添加进度条移动到main for循环,然后将每个栏的引用添加到每个下载器。所以基本上你是在下载开始之前每次下载添加一个进度条,然后在更新时引用自己的下载程序的进度条并更新它。

VideoDownloader downloader = new VideoDownloader(video, Path.Combine(path + "\\", title + video.VideoExtension));
downloader.DownloadProgressChanged += Downloader_DownloadProgressChanged;
downloader.DownloadFinished += Downloader_DownloadFinished;
ProgressBar pb = new ProgressBar(); //new
flowLayoutPanel1.Controls.Add(pb); //new
downloader.ProgressBar = pb;       //new - you will need to add a property to the downloader class

然后在您的活动中,您将修改下载程序进度条值:

private void Downloader_DownloadProgressChanged(object sender, ProgressEventArgs e)
    {
        flowLayoutPanel1.Invoke(new MethodInvoker(delegate
        {
            this.ProgressBar.Value = (int)e.ProgressPercentage; 
        }));

    }