C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C#圆形进度条

C# Winform实现绘制圆形进度条

作者:漂泊_人生

这篇文章主要为大家详细介绍了使用C# Winform实现绘制圆形进度条的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编 一起学习一下

效果图

实现代码

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

方法补充

除了上文的方法,小编还为大家整理了其他C#实现绘制圆形进度条的方法,希望对大家有所帮助

方法一:

首先,在你的WinForms项目中添加一个Panel控件作为进度条的容器。然后,可以通过重写Panel的OnPaint事件来处理绘图逻辑。

using System;  
using System.Drawing;  
using System.Windows.Forms;  
  
public class CircularProgressBar : Panel  
{  
    private int _progress;  
  
    public CircularProgressBar()  
    {  
        this.DoubleBuffered = true; // 双缓冲以减少闪烁  
        this.SetStyle(ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);  
    }  
  
    public int Progress  
    {  
        get { return _progress; }  
        set  
        {  
            if (value < 0) value = 0;  
            if (value > 100) value = 100;  
  
            _progress = value;  
            Invalidate(); // 触发重绘  
        }  
    }  
  
    protected override void OnPaint(PaintEventArgs e)  
    {  
        base.OnPaint(e);  
  
        int diameter = Math.Min(Width, Height) - 1; // 直径等于宽度和高度的最小值减一  
        int radius = diameter / 2; // 半径等于直径的一半  
        int centerX = Width / 2; // 圆心X坐标  
        int centerY = Height / 2; // 圆心Y坐标  
  
        // 绘制进度条背景  
        using (Pen backgroundPen = new Pen(Color.LightGray, 10))  
        {  
            e.Graphics.DrawEllipse(backgroundPen, centerX - radius, centerY - radius, diameter, diameter);  
        }  
  
        // 绘制进度  
        int sweepAngle = 360 * Progress / 100; // 计算扫过的角度  
        using (Pen progressPen = new Pen(Color.Blue, 10))  
        {  
            e.Graphics.DrawArc(progressPen, centerX - radius, centerY - radius, diameter, diameter, -90, sweepAngle);  
        }  
  
        // 绘制进度文本(可选)  
        using (Font textFont = new Font("Arial", 12, FontStyle.Bold))  
        using (Brush textBrush = new SolidBrush(Color.Black))  
        {  
            string text = Progress + "%";  
            e.Graphics.DrawString(text, textFont, textBrush, centerX - e.Graphics.MeasureString(text, textFont).Width / 2, centerY - e.Graphics.MeasureString(text, textFont).Height / 2);  
        }  
    }  
}

然后,你可以在你的WinForms窗体上实例化并使用这个CircularProgressBar控件:

public partial class MainForm : Form  
{  
    private CircularProgressBar circularProgressBar;  
  
    public MainForm()  
    {  
        InitializeComponent();  
  
        circularProgressBar = new CircularProgressBar();  
        circularProgressBar.Dock = DockStyle.Fill;  
        circularProgressBar.Progress = 50; // 设置初始进度为50%  
        this.Controls.Add(circularProgressBar);  
  
        // 你可以通过定时器或其他方式来动态改变进度  
        // 例如:  
        // System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();  
        // timer.Interval = 1000; // 1秒  
        // timer.Tick += (sender, e) => {  
        //     circularProgressBar.Progress = (circularProgressBar.Progress + 1) % 100;  
        // };  
        // timer.Start();  
    }  
}

请注意,这只是一个简单的示例,你可以根据自己的需求调整样式、颜色、字体等属性,甚至添加动画效果。如果你需要更复杂的仪表盘控件,可能需要考虑使用第三方库或自定义绘制更复杂的图形元素。

方法二:

完整代码

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

namespace HZH_Controls.Controls
{
    public partial class UCProcessEllipse : UserControl
    {
        [Description("值改变事件"), Category("自定义")]
        public event EventHandler ValueChanged;

        private Color m_backEllipseColor = Color.FromArgb(22, 160, 133);
        /// <summary>
        /// 圆背景色
        /// </summary>
        [Description("圆背景色"), Category("自定义")]
        public Color BackEllipseColor
        {
            get { return m_backEllipseColor; }
            set
            {
                m_backEllipseColor = value;
                Refresh();
            }
        }

        private Color m_coreEllipseColor = Color.FromArgb(180, 180, 180);
        /// <summary>
        /// 内圆颜色,ShowType=Ring 有效
        /// </summary>
        [Description("内圆颜色,ShowType=Ring 有效"), Category("自定义")]
        public Color CoreEllipseColor
        {
            get { return m_coreEllipseColor; }
            set
            {
                m_coreEllipseColor = value;
                Refresh();
            }
        }

        private Color m_valueColor = Color.FromArgb(255, 77, 59);

        [Description("值圆颜色"), Category("自定义")]
        public Color ValueColor
        {
            get { return m_valueColor; }
            set
            {
                m_valueColor = value;
                Refresh();
            }
        }

        private bool m_isShowCoreEllipseBorder = true;
        /// <summary>
        /// 内圆是否显示边框,ShowType=Ring 有效
        /// </summary>
        [Description("内圆是否显示边框,ShowType=Ring 有效"), Category("自定义")]
        public bool IsShowCoreEllipseBorder
        {
            get { return m_isShowCoreEllipseBorder; }
            set
            {
                m_isShowCoreEllipseBorder = value;
                Refresh();
            }
        }

        private ValueType m_valueType = ValueType.Percent;
        /// <summary>
        /// 值文字类型
        /// </summary>
        [Description("值文字类型"), Category("自定义")]
        public ValueType ValueType
        {
            get { return m_valueType; }
            set
            {
                m_valueType = value;
                Refresh();
            }
        }

        private int m_valueWidth = 30;
        /// <summary>
        /// 外圆值宽度
        /// </summary>
        [Description("外圆值宽度,ShowType=Ring 有效"), Category("自定义")]
        public int ValueWidth
        {
            get { return m_valueWidth; }
            set
            {
                if (value <= 0 || value > Math.Min(this.Width, this.Height))
                    return;
                m_valueWidth = value;
                Refresh();
            }
        }

        private int m_valueMargin = 5;
        /// <summary>
        /// 外圆值间距
        /// </summary>
        [Description("外圆值间距"), Category("自定义")]
        public int ValueMargin
        {
            get { return m_valueMargin; }
            set
            {
                if (value < 0 || m_valueMargin >= m_valueWidth)
                    return;
                m_valueMargin = value;
                Refresh();
            }
        }

        private int m_maxValue = 100;
        /// <summary>
        /// 最大值
        /// </summary>
        [Description("最大值"), Category("自定义")]
        public int MaxValue
        {
            get { return m_maxValue; }
            set
            {
                if (value > m_value || value <= 0)
                    return;
                m_maxValue = value;
                Refresh();
            }
        }

        private int m_value = 0;
        /// <summary>
        /// 当前值
        /// </summary>
        [Description("当前值"), Category("自定义")]
        public int Value
        {
            get { return m_value; }
            set
            {
                if (m_maxValue < value || value <= 0)
                    return;
                m_value = value;
                if (ValueChanged != null)
                {
                    ValueChanged(this, null);
                }
                Refresh();
            }
        }
        private Font m_font = new Font("Arial Unicode MS", 20);
        [Description("文字字体"), Category("自定义")]
        public override Font Font
        {
            get
            {
                return m_font;
            }
            set
            {
                m_font = value;
                Refresh();
            }
        }
        Color m_foreColor = Color.White;
        [Description("文字颜色"), Category("自定义")]
        public override Color ForeColor
        {
            get
            {
                return m_foreColor;
            }
            set
            {
                m_foreColor = value;
                Refresh();
            }
        }

        private ShowType m_showType = ShowType.Ring;

        [Description("显示类型"), Category("自定义")]
        public ShowType ShowType
        {
            get { return m_showType; }
            set
            {
                m_showType = value;
                Refresh();
            }
        }

        public UCProcessEllipse()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.Selectable, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.UserPaint, true);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            var g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;  //使绘图质量最高,即消除锯齿
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = CompositingQuality.HighQuality;

            int intWidth = Math.Min(this.Size.Width, this.Size.Height);
            //底圆
            g.FillEllipse(new SolidBrush(m_backEllipseColor), new Rectangle(new Point(0, 0), new Size(intWidth, intWidth)));
            if (m_showType == HZH_Controls.Controls.ShowType.Ring)
            {
                //中心圆
                int intCore = intWidth - m_valueWidth * 2;
                g.FillEllipse(new SolidBrush(m_coreEllipseColor), new Rectangle(new Point(m_valueWidth, m_valueWidth), new Size(intCore, intCore)));
                //中心圆边框
                if (m_isShowCoreEllipseBorder)
                {
                    g.DrawEllipse(new Pen(m_valueColor, 2), new Rectangle(new Point(m_valueWidth + 1, m_valueWidth + 1), new Size(intCore - 1, intCore - 1)));
                }
                if (m_value > 0 && m_maxValue > 0)
                {
                    float fltPercent = (float)m_value / (float)m_maxValue;
                    if (fltPercent > 1)
                    {
                        fltPercent = 1;
                    }

                    g.DrawArc(new Pen(m_valueColor, m_valueWidth - m_valueMargin * 2), new RectangleF(new Point(m_valueWidth / 2 + m_valueMargin / 4, m_valueWidth / 2 + m_valueMargin / 4), new SizeF(intWidth - m_valueWidth - m_valueMargin / 2 + (m_valueMargin == 0 ? 0 : 1), intWidth - m_valueWidth - m_valueMargin / 2 + (m_valueMargin == 0 ? 0 : 1))), -90, fltPercent * 360);

                    string strValueText = m_valueType == HZH_Controls.Controls.ValueType.Percent ? fltPercent.ToString("0%") : m_value.ToString();
                    System.Drawing.SizeF _txtSize = g.MeasureString(strValueText, this.Font);
                    g.DrawString(strValueText, this.Font, new SolidBrush(this.ForeColor), new PointF((intWidth - _txtSize.Width) / 2 + 1, (intWidth - _txtSize.Height) / 2 + 1));
                }
            }
            else
            {
                if (m_value > 0 && m_maxValue > 0)
                {
                    float fltPercent = (float)m_value / (float)m_maxValue;
                    if (fltPercent > 1)
                    {
                        fltPercent = 1;
                    }

                    g.FillPie(new SolidBrush(m_valueColor), new Rectangle(m_valueMargin, m_valueMargin, intWidth - m_valueMargin * 2, intWidth - m_valueMargin * 2), -90, fltPercent * 360);

                    string strValueText = m_valueType == HZH_Controls.Controls.ValueType.Percent ? fltPercent.ToString("0%") : m_value.ToString();
                    System.Drawing.SizeF _txtSize = g.MeasureString(strValueText, this.Font);
                    g.DrawString(strValueText, this.Font, new SolidBrush(this.ForeColor), new PointF((intWidth - _txtSize.Width) / 2 + 1, (intWidth - _txtSize.Height) / 2 + 1));
                }
            }

        }
    }

    public enum ValueType
    {
        /// <summary>
        /// 百分比
        /// </summary>
        Percent,
        /// <summary>
        /// 数值
        /// </summary>
        Absolute
    }

    public enum ShowType
    {
        /// <summary>
        /// 圆环
        /// </summary>
        Ring,
        /// <summary>
        /// 扇形
        /// </summary>
        Sector
    }
}
namespace HZH_Controls.Controls
{
    partial class UCProcessEllipse
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region 组件设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            components = new System.ComponentModel.Container();
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        }

        #endregion
    }
}

到此这篇关于C# Winform实现绘制圆形进度条的文章就介绍到这了,更多相关C#圆形进度条内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文