(三十八)c#Winform自定义控件-圆形进度条

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

官网:https://www.hzhcontrols.cn

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:HZHControls控件库: HZHControls控件库,c#的winform自定义控件,对触屏具有更好的操作支持,项目是基于framework4.0,完全原生控件开发,没有使用任何第三方控件,你可以放心的用在你的项目中(winfromcontrol/winformcontrol/.net)。还有更丰富的工业控件持续增加中~~~

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 企鹅群568015492

目录

c#Winform自定义控件-目录_c#winform自定义控件-有图标的按钮-CSDN博客

准备工作

我们理一下思路,进度条支持圆环或扇形显示,支持百分比和数值显示

开始

添加一个用户控件,命名UCProcessEllipse

定义2个枚举

复制代码

 1  public enum ValueType
 2     {
 3         /// <summary>
 4         /// 百分比
 5         /// </summary>
 6         Percent,
 7         /// <summary>
 8         /// 数值
 9         /// </summary>
10         Absolute
11     }
12 
13     public enum ShowType
14     {
15         /// <summary>
16         /// 圆环
17         /// </summary>
18         Ring,
19         /// <summary>
20         /// 扇形
21         /// </summary>
22         Sector
23     }

复制代码

添加属性

复制代码

  1  [Description("值改变事件"), Category("自定义")]
  2         public event EventHandler ValueChanged;
  3 
  4         private Color m_backEllipseColor = Color.FromArgb(22, 160, 133);
  5         /// <summary>
  6         /// 圆背景色
  7         /// </summary>
  8         [Description("圆背景色"), Category("自定义")]
  9         public Color BackEllipseColor
 10         {
 11             get { return m_backEllipseColor; }
 12             set
 13             {
 14                 m_backEllipseColor = value;
 15                 Refresh();
 16             }
 17         }
 18 
 19         private Color m_coreEllipseColor = Color.FromArgb(180, 180, 180);
 20         /// <summary>
 21         /// 内圆颜色,ShowType=Ring 有效
 22         /// </summary>
 23         [Description("内圆颜色,ShowType=Ring 有效"), Category("自定义")]
 24         public Color CoreEllipseColor
 25         {
 26             get { return m_coreEllipseColor; }
 27             set
 28             {
 29                 m_coreEllipseColor = value;
 30                 Refresh();
 31             }
 32         }
 33 
 34         private Color m_valueColor = Color.FromArgb(255, 77, 59);
 35 
 36         [Description("值圆颜色"), Category("自定义")]
 37         public Color ValueColor
 38         {
 39             get { return m_valueColor; }
 40             set
 41             {
 42                 m_valueColor = value;
 43                 Refresh();
 44             }
 45         }
 46 
 47         private bool m_isShowCoreEllipseBorder = true;
 48         /// <summary>
 49         /// 内圆是否显示边框,ShowType=Ring 有效
 50         /// </summary>
 51         [Description("内圆是否显示边框,ShowType=Ring 有效"), Category("自定义")]
 52         public bool IsShowCoreEllipseBorder
 53         {
 54             get { return m_isShowCoreEllipseBorder; }
 55             set
 56             {
 57                 m_isShowCoreEllipseBorder = value;
 58                 Refresh();
 59             }
 60         }
 61 
 62         private ValueType m_valueType = ValueType.Percent;
 63         /// <summary>
 64         /// 值文字类型
 65         /// </summary>
 66         [Description("值文字类型"), Category("自定义")]
 67         public ValueType ValueType
 68         {
 69             get { return m_valueType; }
 70             set
 71             {
 72                 m_valueType = value;
 73                 Refresh();
 74             }
 75         }
 76 
 77         private int m_valueWidth = 30;
 78         /// <summary>
 79         /// 外圆值宽度
 80         /// </summary>
 81         [Description("外圆值宽度,ShowType=Ring 有效"), Category("自定义")]
 82         public int ValueWidth
 83         {
 84             get { return m_valueWidth; }
 85             set
 86             {
 87                 if (value <= 0 || value > Math.Min(this.Width, this.Height))
 88                     return;
 89                 m_valueWidth = value;
 90                 Refresh();
 91             }
 92         }
 93 
 94         private int m_valueMargin = 5;
 95         /// <summary>
 96         /// 外圆值间距
 97         /// </summary>
 98         [Description("外圆值间距"), Category("自定义")]
 99         public int ValueMargin
100         {
101             get { return m_valueMargin; }
102             set
103             {
104                 if (value < 0 || m_valueMargin >= m_valueWidth)
105                     return;
106                 m_valueMargin = value;
107                 Refresh();
108             }
109         }
110 
111         private int m_maxValue = 100;
112         /// <summary>
113         /// 最大值
114         /// </summary>
115         [Description("最大值"), Category("自定义")]
116         public int MaxValue
117         {
118             get { return m_maxValue; }
119             set
120             {
121                 if (value > m_value || value <= 0)
122                     return;
123                 m_maxValue = value;
124                 Refresh();
125             }
126         }
127 
128         private int m_value = 0;
129         /// <summary>
130         /// 当前值
131         /// </summary>
132         [Description("当前值"), Category("自定义")]
133         public int Value
134         {
135             get { return m_value; }
136             set
137             {
138                 if (m_maxValue < value || value <= 0)
139                     return;
140                 m_value = value;
141                 if (ValueChanged != null)
142                 {
143                     ValueChanged(this, null);
144                 }
145                 Refresh();
146             }
147         }
148         private Font m_font = new Font("Arial Unicode MS", 20);
149         [Description("文字字体"), Category("自定义")]
150         public override Font Font
151         {
152             get
153             {
154                 return m_font;
155             }
156             set
157             {
158                 m_font = value;
159                 Refresh();
160             }
161         }
162         Color m_foreColor = Color.White;
163         [Description("文字颜色"), Category("自定义")]
164         public override Color ForeColor
165         {
166             get
167             {
168                 return m_foreColor;
169             }
170             set
171             {
172                 m_foreColor = value;
173                 Refresh();
174             }
175         }
176 
177         private ShowType m_showType = ShowType.Ring;
178 
179         [Description("显示类型"), Category("自定义")]
180         public ShowType ShowType
181         {
182             get { return m_showType; }
183             set
184             {
185                 m_showType = value;
186                 Refresh();
187             }
188         }

复制代码

重绘

复制代码

 1   protected override void OnPaint(PaintEventArgs e)
 2         {
 3             base.OnPaint(e);
 4 
 5             var g = e.Graphics;
 6             g.SmoothingMode = SmoothingMode.AntiAlias;  //使绘图质量最高,即消除锯齿
 7             g.InterpolationMode = InterpolationMode.HighQualityBicubic;
 8             g.CompositingQuality = CompositingQuality.HighQuality;
 9 
10             int intWidth = Math.Min(this.Size.Width, this.Size.Height);
11             //底圆
12             g.FillEllipse(new SolidBrush(m_backEllipseColor), new Rectangle(new Point(0, 0), new Size(intWidth, intWidth)));
13             if (m_showType == HZH_Controls.Controls.ShowType.Ring)
14             {
15                 //中心圆
16                 int intCore = intWidth - m_valueWidth * 2;
17                 g.FillEllipse(new SolidBrush(m_coreEllipseColor), new Rectangle(new Point(m_valueWidth, m_valueWidth), new Size(intCore, intCore)));
18                 //中心圆边框
19                 if (m_isShowCoreEllipseBorder)
20                 {
21                     g.DrawEllipse(new Pen(m_valueColor, 2), new Rectangle(new Point(m_valueWidth + 1, m_valueWidth + 1), new Size(intCore - 1, intCore - 1)));
22                 }
23                 if (m_value > 0 && m_maxValue > 0)
24                 {
25                     float fltPercent = (float)m_value / (float)m_maxValue;
26                     if (fltPercent > 1)
27                     {
28                         fltPercent = 1;
29                     }
30 
31                     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);
32 
33                     string strValueText = m_valueType == HZH_Controls.Controls.ValueType.Percent ? fltPercent.ToString("0%") : m_value.ToString();
34                     System.Drawing.SizeF _txtSize = g.MeasureString(strValueText, this.Font);
35                     g.DrawString(strValueText, this.Font, new SolidBrush(this.ForeColor), new PointF((intWidth - _txtSize.Width) / 2 + 1, (intWidth - _txtSize.Height) / 2 + 1));
36                 }
37             }
38             else
39             {
40                 if (m_value > 0 && m_maxValue > 0)
41                 {
42                     float fltPercent = (float)m_value / (float)m_maxValue;
43                     if (fltPercent > 1)
44                     {
45                         fltPercent = 1;
46                     }
47 
48                     g.FillPie(new SolidBrush(m_valueColor), new Rectangle(m_valueMargin, m_valueMargin, intWidth - m_valueMargin * 2, intWidth - m_valueMargin * 2), -90, fltPercent * 360);
49 
50                     string strValueText = m_valueType == HZH_Controls.Controls.ValueType.Percent ? fltPercent.ToString("0%") : m_value.ToString();
51                     System.Drawing.SizeF _txtSize = g.MeasureString(strValueText, this.Font);
52                     g.DrawString(strValueText, this.Font, new SolidBrush(this.ForeColor), new PointF((intWidth - _txtSize.Width) / 2 + 1, (intWidth - _txtSize.Height) / 2 + 1));
53                 }
54             }
55 
56         }

复制代码

完整代码如下

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

用处及效果

最后的话

如果你喜欢的话,请到 HZHControls控件库: HZHControls控件库,c#的winform自定义控件,对触屏具有更好的操作支持,项目是基于framework4.0,完全原生控件开发,没有使用任何第三方控件,你可以放心的用在你的项目中(winfromcontrol/winformcontrol/.net)。还有更丰富的工业控件持续增加中~~~ 点个星 星吧

WinForms中的自定义控件开发允许开发者创建具有特定功能的控件,这些控件可以用于多种应用程序。仪表盘控件是一种常见的自定义控件,它模拟物理仪表盘,用于显示从简单到复杂的各种数据。在C#中开发WinForms仪表盘控件通常涉及以下几个步骤: 1. **创建控件类**:首先,你需要继承自`UserControl`类,创建一个新的类,这个类将作为基础来定义你的仪表盘控件。 2. **设计界面**:在类中,使用设计器或代码来绘制控件的用户界面。这可能包括刻度、指针和数据标签等元素。 3. **编写业务逻辑**:实现控件的数据绑定和逻辑处理,这可能包括如何读取和显示数据,以及如何响应用户的交互。 4. **属性和事件**:定义公共属性来获取和设置控件的外观和行为,如颜色、范围等,并且创建事件以允许外部代码响应特定的用户操作,如值改变等。 5. **测试和调试**:在完成开发后,需要对控件进行彻底的测试,确保在不同情况下都能正确工作。 以下是一个简单的示例代码,展示了如何创建一个基础的仪表盘控件: ```csharp using System; using System.Drawing; using System.Windows.Forms; public class DashboardControl : UserControl { private float value = 0; // 仪表盘的当前值 // 公共属性,允许外部设置仪表盘值 public float Value { get { return value; } set { if (value != this.value) { this.value = value; Invalidate(); // 重绘控件 } } } // 绘制控件 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; // 绘制仪表盘的刻度和指针等 // ... } // 其他方法,如响应用户事件等 } ``` 开发自定义控件是一个复杂的过程,它需要深入了解WinForms框架、GDI+绘图以及可能涉及的动画和数据绑定技术。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值