C# DotNetZip+自定义圆形进度条解压与压缩文件

cs 复制代码
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 Net6_GeneralUiWinFrm
{
    public partial class MainWinFrm : Form
    {
        private DotNetZipHelper dotNetZipHelper;
        public MainWinFrm()
        {
            InitializeComponent();
            dotNetZipHelper=new DotNetZipHelper();
        }



        #region 压缩
        private void BtnCompress_Click(object sender, EventArgs e)
        {
            // Example usage
            List<string> itemsToZip = new List<string> { @"F:\WebApi" };
            string outputZipPath = @"F:\WebApi.zip";
            string taskId = "compressTask"; // Unique ID for the task

            // Call to DotNetZipHelper to compress items
            dotNetZipHelper.callBack += new Action<int>((i) => {
                this.circularProgressBar.Progress = i;
            });
            Task.Run(() =>
            {
                dotNetZipHelper.CreateZip(outputZipPath, itemsToZip, taskId);
            });
        }
        #endregion

        #region 解压
        private void BtnExtract_Click(object sender, EventArgs e)
        {
            string zipFilePath = @"F:\WebApi.zip";
            string outputFolder = @"E:\WebApi";
            string taskId = "extractTask"; // Unique ID for the task

            // Call to DotNetZipHelper to extract ZIP
            dotNetZipHelper.callBack += new Action<int>((i) => { this.circularProgressBar.Progress = i; });
            Task.Run(() =>
            {
                dotNetZipHelper.ExtractZip(zipFilePath, outputFolder, taskId);
            });
        }
        #endregion
    }

    //public static class ProgressStore
    //{
    //    // Example implementation of ProgressStore
    //    public static void UpdateProgress(string taskId, int progress)
    //    {
    //        // Assuming circularProgressBar1 is accessible, update its progress
    //        // This needs to be invoked on the UI thread
    //        var form = Application.OpenForms["MainWinFrm"] as MainWinFrm;
    //        form?.Invoke(new Action(() =>
    //        {
    //            form.circularProgressBar.Progress = progress;
    //        }));
    //    }

    //    public static void RemoveProgress(string taskId)
    //    {
    //        // Reset progress to 0 or remove the task's progress tracking
    //        var form = Application.OpenForms["MainWinFrm"] as MainWinFrm;
    //        form?.Invoke(new Action(() =>
    //        {
    //            form.circularProgressBar.Progress = 0;
    //        }));
    //    }
    //}

    // Include CircularProgressBar class here
}
cs 复制代码
namespace Net6_GeneralUiWinFrm
{
    partial class MainWinFrm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            splitContainer1 = new SplitContainer();
            circularProgressBar = new CircularProgressBar();
            BtnExtract = new Button();
            BtnCompress = new Button();
            ((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
            splitContainer1.Panel1.SuspendLayout();
            splitContainer1.Panel2.SuspendLayout();
            splitContainer1.SuspendLayout();
            SuspendLayout();
            // 
            // splitContainer1
            // 
            splitContainer1.Dock = DockStyle.Fill;
            splitContainer1.Location = new Point(0, 0);
            splitContainer1.Name = "splitContainer1";
            splitContainer1.Orientation = Orientation.Horizontal;
            // 
            // splitContainer1.Panel1
            // 
            splitContainer1.Panel1.Controls.Add(circularProgressBar);
            // 
            // splitContainer1.Panel2
            // 
            splitContainer1.Panel2.Controls.Add(BtnExtract);
            splitContainer1.Panel2.Controls.Add(BtnCompress);
            splitContainer1.Size = new Size(800, 497);
            splitContainer1.SplitterDistance = 384;
            splitContainer1.TabIndex = 0;
            // 
            // circularProgressBar
            // 
            circularProgressBar.Location = new Point(212, 32);
            circularProgressBar.Name = "circularProgressBar";
            circularProgressBar.Progress = 0;
            circularProgressBar.Size = new Size(346, 325);
            circularProgressBar.TabIndex = 1;
            circularProgressBar.Text = "circularProgressBar";
            // 
            // BtnExtract
            // 
            BtnExtract.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
            BtnExtract.Location = new Point(431, 35);
            BtnExtract.Name = "BtnExtract";
            BtnExtract.Size = new Size(170, 43);
            BtnExtract.TabIndex = 0;
            BtnExtract.Text = "解压缩(&E)";
            BtnExtract.UseVisualStyleBackColor = true;
            BtnExtract.Click += BtnExtract_Click;
            // 
            // BtnCompress
            // 
            BtnCompress.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
            BtnCompress.Location = new Point(222, 35);
            BtnCompress.Name = "BtnCompress";
            BtnCompress.Size = new Size(170, 43);
            BtnCompress.TabIndex = 0;
            BtnCompress.Text = "压缩(&C)";
            BtnCompress.UseVisualStyleBackColor = true;
            BtnCompress.Click += BtnCompress_Click;
            // 
            // MainWinFrm
            // 
            AutoScaleDimensions = new SizeF(7F, 17F);
            AutoScaleMode = AutoScaleMode.Font;
            ClientSize = new Size(800, 497);
            Controls.Add(splitContainer1);
            Name = "MainWinFrm";
            Text = "MainWinFrm";
            splitContainer1.Panel1.ResumeLayout(false);
            splitContainer1.Panel2.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)splitContainer1).EndInit();
            splitContainer1.ResumeLayout(false);
            ResumeLayout(false);
        }

        #endregion

        private SplitContainer splitContainer1;
        public CircularProgressBar circularProgressBar;
        private Button BtnCompress;
        private Button BtnExtract;
    }
}
cs 复制代码
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace Net6_GeneralUiWinFrm
{
        public class CircularProgressBar : Control
        {
            private int progress = 0;
            private int borderWidth = 20; // 增加的边框宽度

            public int Progress
            {
                get { return progress; }
                set
                {
                    progress = Math.Max(0, Math.Min(100, value)); // 确保进度值在0到100之间
                    Invalidate(); // Causes the control to be redrawn
                }
            }

            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);
                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

                // Draw background circle
                using (Pen pen = new Pen(Color.LightGray, borderWidth))
                {
                    pen.DashStyle = DashStyle.Dot; // 设置点状线条
                    e.Graphics.DrawEllipse(pen, borderWidth / 2, borderWidth / 2, this.Width - borderWidth, this.Height - borderWidth);
                }

                // Draw progress arc
                using (Pen pen = new Pen(Color.LightGreen, borderWidth)) //lightgreen
                {
                    pen.DashStyle = DashStyle.Solid; // 进度使用实线
                                                     // Calculate sweep angle
                    float sweepAngle = (360f * progress) / 100f;
                    e.Graphics.DrawArc(pen, borderWidth / 2, borderWidth / 2, this.Width - borderWidth, this.Height - borderWidth, -90, sweepAngle);
                }

                // Draw progress text
                string progressText = $"{progress}%";
                using (Font font = new Font("Arial", 12))
                using (Brush brush = new SolidBrush(Color.Black))
                {
                    SizeF textSize = e.Graphics.MeasureString(progressText, font);
                    // Calculate text position
                    PointF textPoint = new PointF((this.Width - textSize.Width) / 2, (this.Height - textSize.Height) / 2);
                    e.Graphics.DrawString(progressText, font, brush, textPoint);
                }
            }
        }
}
cs 复制代码
using Common;
using Ionic.Zip;

public class DotNetZipHelper
{
    // 示例:压缩文件并更新进度
    public int progress=0;
    public event Action<int> callBack;
    public void CreateZip(string outputZipPath, List<string> itemsToZip, string taskId)
    {
        progress = 0;
        using (ZipFile zip = new ZipFile())
        {
            zip.UseZip64WhenSaving = Zip64Option.Always; // 启用ZIP64格式支持
            zip.AlternateEncoding = System.Text.Encoding.UTF8; // 使用 UTF-8 编码
            zip.AlternateEncodingUsage = ZipOption.Always; // 始终使用指定编码

            // 订阅SaveProgress事件
            zip.SaveProgress += (sender, e) =>
            {
                if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry)
                {
                    progress = (int)((e.EntriesSaved / (float)e.EntriesTotal) * 100);
                    this.callBack?.Invoke(progress);
                }
                else if (e.EventType == ZipProgressEventType.Saving_Completed)
                {
                    this.callBack?.Invoke(100); // 确保在完成时报告100%进度
                }
            };

            foreach (var item in itemsToZip)
            {
                if (File.Exists(item))
                {
                    zip.AddFile(item, "");
                }
                else if (Directory.Exists(item))
                {
                    zip.AddDirectory(item, Path.GetFileName(item));
                }
            }

            zip.Save(outputZipPath);
        }

        ProgressStore.RemoveProgress(taskId);
    }



    // 示例:解压缩文件并更新进度
    public void ExtractZip(string zipFilePath, string outputFolder, string taskId)
    {
        progress = 0;

        if (!Directory.Exists(outputFolder))
        {
            Directory.CreateDirectory(outputFolder);
        }

        using (ZipFile zip = ZipFile.Read(zipFilePath))
        {
            zip.AlternateEncoding = System.Text.Encoding.UTF8; // 使用 UTF-8 编码
            zip.AlternateEncodingUsage = ZipOption.Always; // 始终使用指定编码

            int total = zip.Count;
            int current = 0;

            foreach (ZipEntry e in zip)
            {
                try
                {
                    e.Extract(outputFolder, ExtractExistingFileAction.OverwriteSilently);
                    current++;
                    progress = (int)((current / (float)total) * 100);
                    this.callBack?.Invoke(progress);
                }
                catch (IOException ex)
                {
                    Console.WriteLine($"无法解压文件:{e.FileName},错误:{ex.Message}");
                    // 考虑是否需要在此处更新进度或处理异常
                    continue;
                }
            }
        }

        ProgressStore.RemoveProgress(taskId);
    }

}
相关推荐
代码小鑫10 分钟前
A032-基于Spring Boot的健康医院门诊在线挂号系统
java·开发语言·spring boot·后端·spring·毕业设计
昔舍15 分钟前
C#笔记(3)
笔记·c#
训山18 分钟前
4000字浅谈Java网络编程
java·开发语言·网络
API快乐传递者19 分钟前
除了网页标题,还能用爬虫抓取哪些信息?
开发语言·爬虫·python
hutaotaotao1 小时前
c语言用户不同命令调用不同函数实现
c语言·开发语言
huangjiazhi_1 小时前
QTcpSocket 服务端和客户端
开发语言·qt
ac-er88881 小时前
ThinkPHP中的MVC分层是什么
开发语言·php·mvc
吾与谁归in2 小时前
【C#设计模式(4)——构建者模式(Builder Pattern)】
设计模式·c#·建造者模式
shinelord明2 小时前
【再谈设计模式】建造者模式~对象构建的指挥家
开发语言·数据结构·设计模式
黑不拉几的小白兔2 小时前
PTA部分题目C++重练
开发语言·c++·算法