winforms 如何向progressBar报告下载文件的进度,而不是报告整体进度,而不是每个文件的进度?

6yjfywim  于 2022-11-17  发布在  其他
关注(0)|答案(1)|浏览(135)
public void DownloadFile(string urlAddress, string location)
        {
            Stopwatch sw = new Stopwatch();
            using (WebClient webClient = new WebClient())
            {
                webClient.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0 Chrome");
                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler((sender, e) => Completed(sender, e, sw));
                webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler((sender, e) => ProgressChanged(sender, e, sw));
                Uri URL = new Uri(urlAddress);
                sw.Start();
                try
                {
                    webClient.DownloadFileAsync(URL, location);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e, Stopwatch sw)
        {
            string downloadProgress = e.ProgressPercentage + "%";
            string downloadSpeed = string.Format("{0} MB/s", (e.BytesReceived / 1024.0 / 1024.0 / sw.Elapsed.TotalSeconds).ToString("0.00"));
            string downloadedMBs = Math.Round(e.BytesReceived / 1024.0 / 1024.0) + " MB";
            string totalMBs = Math.Round(e.TotalBytesToReceive / 1024.0 / 1024.0) + " MB";

            // Format progress string
            string progress = $"{downloadedMBs}/{totalMBs} ({downloadProgress}) @ {downloadSpeed}"; // 10 MB / 100 MB (10%) @ 1.23 MB/s

            progressBarText1.Value = e.ProgressPercentage;
            progressBarText1.Refresh();
            progressBarText1.CustomText = progress;
        }

        private void Completed(object sender, AsyncCompletedEventArgs e, Stopwatch sw)
        {
            if (e.Cancelled == true)
            {
                btnStartDownload.Text = "Fails.";
                sw.Stop();
            }
            else
            {
                btnStartDownload.Text = "Finish.";
                sw.Stop();

                if (videosLinks.Count > 0)
                {
                    videosLinks.RemoveAt(0);
                    string fileName = System.IO.Path.GetFileName(videosLinks[0]);
                    DownloadFile(videosLinks[0], @"D:\Videos\videos\" + fileName);
                }
            }
        }

        static readonly string[] SizeSuffixes =
                  { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
        static string SizeSuffix(Int64 value, Int64 totalValue)
        {
            if (value < 0) { return "-" + SizeSuffix(-value, totalValue); }

            int i = 0;
            decimal dValue = (decimal)value;
            while (Math.Round(dValue / 1024) >= 1)
            {
                dValue /= 1024;
                i++;
            }

            return string.Format("{0:n1} {1} {2}", dValue, SizeSuffixes[i], (totalValue / 1024d / 1024d).ToString("0.00"));
        }

这是正常的,但它报告的是每个文件的下载进度。
我如何才能使它也将报告整体下载的进度?我添加了另一个名为progressBar2的进度条,我想报告整体下载过程,而不是像我对progressBar1所做的那样按文件报告。

gt0wga4j

gt0wga4j1#

这是一个可行的解决方案。

using System;
using System.Buffers;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;
 
namespace Download_Videos
{
    public partial class Form1 : Form
    {
        private List<string> videosLinks = new List<string>();
        private int filesCounter = 0;
        long sizes = 0;
        long _received = 0;
 
        public Form1()
        {
            InitializeComponent();
 
            progressBarText1.DisplayStyle = ProgressBarDisplayText.CustomText;
            lblFilesCount.Text = "";
 
            string[] files = Directory.GetFiles(@"C:\Users\tester\OneDrive\randfiles\");
            foreach(string file in files)
            {
                videosLinks.Add(file);
            }
            lblFilesCount.Text = videosLinks.Count.ToString();
            filesCounter = videosLinks.Count;
 
            foreach(string file in files)
            {
                long size = new System.IO.FileInfo(file).Length;
                sizes = sizes + size;
            }
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
 
        }
 
        private void DownloadSources(string sourceLink, string destFile)
        {
            using (WebClient client = new WebClient())
            {
                client.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0 Chrome");
                client.DownloadFile(sourceLink, destFile);
            }
        }
 
        private void btnStartDownload_Click(object sender, EventArgs e)
        {
            if (videosLinks.Count > 0)
            {
                string fileName = System.IO.Path.GetFileName(videosLinks[0]);
                DownloadFile(videosLinks[0], @"D:\Videos\videos\" + fileName);
            }
        }
 
        public void DownloadFile(string urlAddress, string location)
        {
            Stopwatch sw = new Stopwatch();
            using (WebClient webClient = new WebClient())
            {
                webClient.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0 Chrome");
                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler((sender, e) => Completed(sender, e, sw));
                webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler((sender, e) => ProgressChanged(sender, e, sw));
 
                Uri URL = new Uri(urlAddress);
                sw.Start();
                try
                {
                    webClient.DownloadFileAsync(URL, location);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
 
        private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e, Stopwatch sw)
        {
            string downloadProgress = e.ProgressPercentage + "%";
            string downloadSpeed = string.Format("{0} MB/s", (e.BytesReceived / 1024.0 / 1024.0 / sw.Elapsed.TotalSeconds).ToString("0.00"));
            string downloadedMBs = Math.Round(e.BytesReceived / 1024.0 / 1024.0) + " MB";
            string totalMBs = Math.Round(e.TotalBytesToReceive / 1024.0 / 1024.0) + " MB";
 
            // Format progress string
            string progress = $"{downloadedMBs}/{totalMBs} ({downloadProgress}) @ {downloadSpeed}"; // 10 MB / 100 MB (10%) @ 1.23 MB/s
 
            progressBarText1.Value = e.ProgressPercentage;
            progressBarText1.Refresh();
            progressBarText1.CustomText = progress;
 
            var result = (double)(_received + e.BytesReceived) / sizes * 100;
            progressBarText2.Value = (int)result;
            progressBarText2.Refresh();
        }
 
        private void Completed(object sender, AsyncCompletedEventArgs e, Stopwatch sw)
        {
            if (e.Cancelled == true)
            {
                btnStartDownload.Text = "Fails.";
                sw.Stop();
            }
            else
            {
                btnStartDownload.Text = "Finish.";
                sw.Stop();
 
                filesCounter--;
                lblFilesCount.Text = filesCounter.ToString();
                var size = new FileInfo(videosLinks[0]);
                _received += size.Length;
                videosLinks.RemoveAt(0);
                if (videosLinks.Count > 0)
                {
                    string fileName = System.IO.Path.GetFileName(videosLinks[0]);
                    DownloadFile(videosLinks[0], @"D:\Videos\videos\" + fileName);
 
 
                }
                else
                {
                    progressBarText1.CustomText = "";
                }
            }
        }
 
        static readonly string[] SizeSuffixes =
                  { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
        static string SizeSuffix(Int64 value, Int64 totalValue)
        {
            if (value < 0) { return "-" + SizeSuffix(-value, totalValue); }
 
            int i = 0;
            decimal dValue = (decimal)value;
            while (Math.Round(dValue / 1024) >= 1)
            {
                dValue /= 1024;
                i++;
            }
 
            return string.Format("{0:n1} {1} {2}", dValue, SizeSuffixes[i], (totalValue / 1024d / 1024d).ToString("0.00"));
        }
    }
}

progressBarText类型是一个自定义进度栏:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Download_Videos
{
    public enum ProgressBarDisplayText
    {
        Percentage,
        CustomText
    }

    public partial class ProgressBarText : ProgressBar
    {
        //Property to set to decide whether to print a % or Text
        public ProgressBarDisplayText DisplayStyle { get; set; }
        
        //Property to hold the custom text
        public String CustomText { get; set; }

        public ProgressBarText()
        {
            // Modify the ControlStyles flags
            //http://msdn.microsoft.com/en-us/library/system.windows.forms.controlstyles.aspx
            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Rectangle rect = ClientRectangle;
            Graphics g = e.Graphics;

            ProgressBarRenderer.DrawHorizontalBar(g, rect);
            rect.Inflate(-3, -3);
            if (Value > 0)
            {
                // As we doing this ourselves we need to draw the chunks on the progress bar
                Rectangle clip = new Rectangle(rect.X, rect.Y, (int)Math.Round(((float)Value / Maximum) * rect.Width), rect.Height);
                ProgressBarRenderer.DrawHorizontalChunks(g, clip);
            }

            // Set the Display text (Either a % amount or our custom text
            int percent = (int)(((double)this.Value / (double)this.Maximum) * 100);
            string text = DisplayStyle == ProgressBarDisplayText.Percentage ? percent.ToString() + '%' : CustomText;

            using (Font f = new Font(FontFamily.GenericSerif, 14))
            {

                SizeF len = g.MeasureString(text, f);
                // Calculate the location of the text (the middle of progress bar)
                // Point location = new Point(Convert.ToInt32((rect.Width / 2) - (len.Width / 2)), Convert.ToInt32((rect.Height / 2) - (len.Height / 2)));
                Point location = new Point(Convert.ToInt32((Width / 2) - len.Width / 2), Convert.ToInt32((Height / 2) - len.Height / 2));
                // The commented-out code will centre the text into the highlighted area only. This will centre the text regardless of the highlighted area.
                // Draw the custom text
                g.DrawString(text, f, Brushes.Blue, location);
            }
        }
    }
}

相关问题