(四十六)c#Winform自定义控件-水波进度条

前提

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

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

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

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

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

麻烦博客下方点个【推荐】,谢谢

NuGet

Install-Package HZH_Controls

目录

https://www.cnblogs.com/bfyx/p/11364884.html

用处及效果

准备工作

这个用到GDI+画的,请先了解一下GDI+

还有用到了基类控件UCControlBase来控制圆角和背景色,如果还不了解请移步查看

(一)c#Winform自定义控件-基类控件

另外用到了水波控件UCWave,如果不了解请移步查看

(四十四)c#Winform自定义控件-水波

开始

添加一个用户控件UCProcessWave,继承UCControlBase

一些属性

  1   private bool m_isRectangle = false;
  2         [Description("是否矩形"), Category("自定义")]
  3         public bool IsRectangle
  4         {
  5             get { return m_isRectangle; }
  6             set
  7             {
  8                 m_isRectangle = value;
  9                 if (value)
 10                 {
 11                     base.ConerRadius = 10;
 12                 }
 13                 else
 14                 {
 15                     base.ConerRadius = Math.Min(this.Width, this.Height);
 16                 }
 17             }
 18         }
 19         #region 不再使用的父类属性    English:Parent class attributes that are no longer used
 20         [Browsable(false)]
 21         public new int ConerRadius
 22         {
 23             get;
 24             set;
 25         }
 26         [Browsable(false)]
 27         public new bool IsRadius
 28         {
 29             get;
 30             set;
 31         }
 32
 33         [Browsable(false)]
 34         public new Color FillColor
 35         {
 36             get;
 37             set;
 38         }
 39         #endregion
 40
 41
 42         [Description("值变更事件"), Category("自定义")]
 43         public event EventHandler ValueChanged;
 44         int m_value = 0;
 45         [Description("当前属性"), Category("自定义")]
 46         public int Value
 47         {
 48             set
 49             {
 50                 if (value > m_maxValue)
 51                     m_value = m_maxValue;
 52                 else if (value < 0)
 53                     m_value = 0;
 54                 else
 55                     m_value = value;
 56                 if (ValueChanged != null)
 57                     ValueChanged(this, null);
 58                 ucWave1.Height = (int)((double)m_value / (double)m_maxValue * this.Height) + ucWave1.WaveHeight;
 59                 Refresh();
 60             }
 61             get
 62             {
 63                 return m_value;
 64             }
 65         }
 66
 67         private int m_maxValue = 100;
 68
 69         [Description("最大值"), Category("自定义")]
 70         public int MaxValue
 71         {
 72             get { return m_maxValue; }
 73             set
 74             {
 75                 if (value < m_value)
 76                     m_maxValue = m_value;
 77                 else
 78                     m_maxValue = value;
 79                 Refresh();
 80             }
 81         }
 82
 83         public override Font Font
 84         {
 85             get
 86             {
 87                 return base.Font;
 88             }
 89             set
 90             {
 91                 base.Font = value;
 92             }
 93         }
 94
 95         public override Color ForeColor
 96         {
 97             get
 98             {
 99                 return base.ForeColor;
100             }
101             set
102             {
103                 base.ForeColor = value;
104             }
105         }
106
107         [Description("值颜色"), Category("自定义")]
108         public Color ValueColor
109         {
110             get { return this.ucWave1.WaveColor; }
111             set
112             {
113                 this.ucWave1.WaveColor = value;
114             }
115         }
116
117         [Description("边框宽度"), Category("自定义")]
118         public override int RectWidth
119         {
120             get
121             {
122                 return base.RectWidth;
123             }
124             set
125             {
126                 if (value < 4)
127                     base.RectWidth = 4;
128                 else
129                     base.RectWidth = value;
130             }
131         }

构造函数一些设置

 1  public UCProcessWave()
 2         {
 3             InitializeComponent();
 4             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
 5             this.SetStyle(ControlStyles.DoubleBuffer, true);
 6             this.SetStyle(ControlStyles.ResizeRedraw, true);
 7             this.SetStyle(ControlStyles.Selectable, true);
 8             this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
 9             this.SetStyle(ControlStyles.UserPaint, true);
10             base.IsRadius = true;
11             base.IsShowRect = false;
12             RectWidth = 4;
13             RectColor = Color.White;
14             ucWave1.Height = (int)((double)m_value / (double)m_maxValue * this.Height) + ucWave1.WaveHeight;
15             this.SizeChanged += UCProcessWave_SizeChanged;
16             this.ucWave1.OnPainted += ucWave1_Painted;
17             base.ConerRadius = Math.Min(this.Width, this.Height);
18         }

重绘

 1  protected override void OnPaint(PaintEventArgs e)
 2         {
 3             base.OnPaint(e);
 4             e.Graphics.SetGDIHigh();
 5             if (!m_isRectangle)
 6             {
 7                 //这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡
 8                 SolidBrush solidBrush = new SolidBrush(Color.White);
 9                 e.Graphics.DrawEllipse(new Pen(solidBrush, 2), new Rectangle(-1, -1, this.Width + 2, this.Height + 2));
10             }
11             string strValue = ((double)m_value / (double)m_maxValue).ToString("0.%");
12             System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
13             e.Graphics.DrawString(strValue, Font, new SolidBrush(ForeColor), new PointF((this.Width - sizeF.Width) / 2, (this.Height - sizeF.Height) / 2 + 1));
14         }

波形控件重绘时处理

 1   void ucWave1_Painted(object sender, PaintEventArgs e)
 2         {
 3             e.Graphics.SetGDIHigh();
 4             if (IsShowRect)
 5             {
 6                 if (m_isRectangle)
 7                 {
 8                     Color rectColor = RectColor;
 9                     Pen pen = new Pen(rectColor, (float)RectWidth);
10                     Rectangle clientRectangle = new Rectangle(0, this.ucWave1.Height - this.Height, this.Width, this.Height);
11                     GraphicsPath graphicsPath = new GraphicsPath();
12                     graphicsPath.AddArc(clientRectangle.X, clientRectangle.Y, 10, 10, 180f, 90f);
13                     graphicsPath.AddArc(clientRectangle.Width - 10 - 1, clientRectangle.Y, 10, 10, 270f, 90f);
14                     graphicsPath.AddArc(clientRectangle.Width - 10 - 1, clientRectangle.Bottom - 10 - 1, 10, 10, 0f, 90f);
15                     graphicsPath.AddArc(clientRectangle.X, clientRectangle.Bottom - 10 - 1, 10, 10, 90f, 90f);
16                     graphicsPath.CloseFigure();
17                     e.Graphics.DrawPath(pen, graphicsPath);
18                 }
19                 else
20                 {
21                     SolidBrush solidBrush = new SolidBrush(RectColor);
22                     e.Graphics.DrawEllipse(new Pen(solidBrush, RectWidth), new Rectangle(0, this.ucWave1.Height - this.Height, this.Width, this.Height));
23                 }
24             }
25
26             if (!m_isRectangle)
27             {
28                 //这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡
29                 SolidBrush solidBrush1 = new SolidBrush(Color.White);
30                 e.Graphics.DrawEllipse(new Pen(solidBrush1, 2), new Rectangle(-1, this.ucWave1.Height - this.Height - 1, this.Width + 2, this.Height + 2));
31             }
32             string strValue = ((double)m_value / (double)m_maxValue).ToString("0.%");
33             System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
34             e.Graphics.DrawString(strValue, Font, new SolidBrush(ForeColor), new PointF((this.Width - sizeF.Width) / 2, (this.ucWave1.Height - this.Height) + (this.Height - sizeF.Height) / 2));
35         }

不知道你们有没有注意这句话

 //这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡

因为设置原价导致了区域毛边,所有画个没有毛边的边框覆盖之

完整代码

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Drawing;
  5 using System.Data;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using System.Drawing.Drawing2D;
 10
 11 namespace HZH_Controls.Controls
 12 {
 13     public partial class UCProcessWave : UCControlBase
 14     {
 15         private bool m_isRectangle = false;
 16         [Description("是否矩形"), Category("自定义")]
 17         public bool IsRectangle
 18         {
 19             get { return m_isRectangle; }
 20             set
 21             {
 22                 m_isRectangle = value;
 23                 if (value)
 24                 {
 25                     base.ConerRadius = 10;
 26                 }
 27                 else
 28                 {
 29                     base.ConerRadius = Math.Min(this.Width, this.Height);
 30                 }
 31             }
 32         }
 33         #region 不再使用的父类属性    English:Parent class attributes that are no longer used
 34         [Browsable(false)]
 35         public new int ConerRadius
 36         {
 37             get;
 38             set;
 39         }
 40         [Browsable(false)]
 41         public new bool IsRadius
 42         {
 43             get;
 44             set;
 45         }
 46
 47         [Browsable(false)]
 48         public new Color FillColor
 49         {
 50             get;
 51             set;
 52         }
 53         #endregion
 54
 55
 56         [Description("值变更事件"), Category("自定义")]
 57         public event EventHandler ValueChanged;
 58         int m_value = 0;
 59         [Description("当前属性"), Category("自定义")]
 60         public int Value
 61         {
 62             set
 63             {
 64                 if (value > m_maxValue)
 65                     m_value = m_maxValue;
 66                 else if (value < 0)
 67                     m_value = 0;
 68                 else
 69                     m_value = value;
 70                 if (ValueChanged != null)
 71                     ValueChanged(this, null);
 72                 ucWave1.Height = (int)((double)m_value / (double)m_maxValue * this.Height) + ucWave1.WaveHeight;
 73                 Refresh();
 74             }
 75             get
 76             {
 77                 return m_value;
 78             }
 79         }
 80
 81         private int m_maxValue = 100;
 82
 83         [Description("最大值"), Category("自定义")]
 84         public int MaxValue
 85         {
 86             get { return m_maxValue; }
 87             set
 88             {
 89                 if (value < m_value)
 90                     m_maxValue = m_value;
 91                 else
 92                     m_maxValue = value;
 93                 Refresh();
 94             }
 95         }
 96
 97         public override Font Font
 98         {
 99             get
100             {
101                 return base.Font;
102             }
103             set
104             {
105                 base.Font = value;
106             }
107         }
108
109         public override Color ForeColor
110         {
111             get
112             {
113                 return base.ForeColor;
114             }
115             set
116             {
117                 base.ForeColor = value;
118             }
119         }
120
121         [Description("值颜色"), Category("自定义")]
122         public Color ValueColor
123         {
124             get { return this.ucWave1.WaveColor; }
125             set
126             {
127                 this.ucWave1.WaveColor = value;
128             }
129         }
130
131         [Description("边框宽度"), Category("自定义")]
132         public override int RectWidth
133         {
134             get
135             {
136                 return base.RectWidth;
137             }
138             set
139             {
140                 if (value < 4)
141                     base.RectWidth = 4;
142                 else
143                     base.RectWidth = value;
144             }
145         }
146
147         public UCProcessWave()
148         {
149             InitializeComponent();
150             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
151             this.SetStyle(ControlStyles.DoubleBuffer, true);
152             this.SetStyle(ControlStyles.ResizeRedraw, true);
153             this.SetStyle(ControlStyles.Selectable, true);
154             this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
155             this.SetStyle(ControlStyles.UserPaint, true);
156             base.IsRadius = true;
157             base.IsShowRect = false;
158             RectWidth = 4;
159             RectColor = Color.White;
160             ucWave1.Height = (int)((double)m_value / (double)m_maxValue * this.Height) + ucWave1.WaveHeight;
161             this.SizeChanged += UCProcessWave_SizeChanged;
162             this.ucWave1.OnPainted += ucWave1_Painted;
163             base.ConerRadius = Math.Min(this.Width, this.Height);
164         }
165
166         void ucWave1_Painted(object sender, PaintEventArgs e)
167         {
168             e.Graphics.SetGDIHigh();
169             if (IsShowRect)
170             {
171                 if (m_isRectangle)
172                 {
173                     Color rectColor = RectColor;
174                     Pen pen = new Pen(rectColor, (float)RectWidth);
175                     Rectangle clientRectangle = new Rectangle(0, this.ucWave1.Height - this.Height, this.Width, this.Height);
176                     GraphicsPath graphicsPath = new GraphicsPath();
177                     graphicsPath.AddArc(clientRectangle.X, clientRectangle.Y, 10, 10, 180f, 90f);
178                     graphicsPath.AddArc(clientRectangle.Width - 10 - 1, clientRectangle.Y, 10, 10, 270f, 90f);
179                     graphicsPath.AddArc(clientRectangle.Width - 10 - 1, clientRectangle.Bottom - 10 - 1, 10, 10, 0f, 90f);
180                     graphicsPath.AddArc(clientRectangle.X, clientRectangle.Bottom - 10 - 1, 10, 10, 90f, 90f);
181                     graphicsPath.CloseFigure();
182                     e.Graphics.DrawPath(pen, graphicsPath);
183                 }
184                 else
185                 {
186                     SolidBrush solidBrush = new SolidBrush(RectColor);
187                     e.Graphics.DrawEllipse(new Pen(solidBrush, RectWidth), new Rectangle(0, this.ucWave1.Height - this.Height, this.Width, this.Height));
188                 }
189             }
190
191             if (!m_isRectangle)
192             {
193                 //这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡
194                 SolidBrush solidBrush1 = new SolidBrush(Color.White);
195                 e.Graphics.DrawEllipse(new Pen(solidBrush1, 2), new Rectangle(-1, this.ucWave1.Height - this.Height - 1, this.Width + 2, this.Height + 2));
196             }
197             string strValue = ((double)m_value / (double)m_maxValue).ToString("0.%");
198             System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
199             e.Graphics.DrawString(strValue, Font, new SolidBrush(ForeColor), new PointF((this.Width - sizeF.Width) / 2, (this.ucWave1.Height - this.Height) + (this.Height - sizeF.Height) / 2));
200         }
201
202         void UCProcessWave_SizeChanged(object sender, EventArgs e)
203         {
204             if (!m_isRectangle)
205             {
206                 base.ConerRadius = Math.Min(this.Width, this.Height);
207                 if (this.Width != this.Height)
208                 {
209                     this.Size = new Size(Math.Min(this.Width, this.Height), Math.Min(this.Width, this.Height));
210                 }
211             }
212         }
213
214         protected override void OnPaint(PaintEventArgs e)
215         {
216             base.OnPaint(e);
217             e.Graphics.SetGDIHigh();
218             if (!m_isRectangle)
219             {
220                 //这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡
221                 SolidBrush solidBrush = new SolidBrush(Color.White);
222                 e.Graphics.DrawEllipse(new Pen(solidBrush, 2), new Rectangle(-1, -1, this.Width + 2, this.Height + 2));
223             }
224             string strValue = ((double)m_value / (double)m_maxValue).ToString("0.%");
225             System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
226             e.Graphics.DrawString(strValue, Font, new SolidBrush(ForeColor), new PointF((this.Width - sizeF.Width) / 2, (this.Height - sizeF.Height) / 2 + 1));
227         }
228     }
229 }

 1 namespace HZH_Controls.Controls
 2 {
 3     partial class UCProcessWave
 4     {
 5         /// <summary>
 6         /// 必需的设计器变量。
 7         /// </summary>
 8         private System.ComponentModel.IContainer components = null;
 9
10         /// <summary>
11         /// 清理所有正在使用的资源。
12         /// </summary>
13         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
14         protected override void Dispose(bool disposing)
15         {
16             if (disposing && (components != null))
17             {
18                 components.Dispose();
19             }
20             base.Dispose(disposing);
21         }
22
23         #region 组件设计器生成的代码
24
25         /// <summary>
26         /// 设计器支持所需的方法 - 不要
27         /// 使用代码编辑器修改此方法的内容。
28         /// </summary>
29         private void InitializeComponent()
30         {
31             this.ucWave1 = new HZH_Controls.Controls.UCWave();
32             this.SuspendLayout();
33             //
34             // ucWave1
35             //
36             this.ucWave1.Dock = System.Windows.Forms.DockStyle.Bottom;
37             this.ucWave1.Location = new System.Drawing.Point(0, 140);
38             this.ucWave1.Name = "ucWave1";
39             this.ucWave1.Size = new System.Drawing.Size(150, 10);
40             this.ucWave1.TabIndex = 0;
41             this.ucWave1.Text = "ucWave1";
42             this.ucWave1.WaveColor = System.Drawing.Color.FromArgb(((int)(((byte)(73)))), ((int)(((byte)(119)))), ((int)(((byte)(232)))));
43             this.ucWave1.WaveHeight = 15;
44             this.ucWave1.WaveSleep = 100;
45             this.ucWave1.WaveWidth = 100;
46             //
47             // UCProcessWave
48             //
49             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
50             this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(197)))), ((int)(((byte)(229)))), ((int)(((byte)(250)))));
51             this.Controls.Add(this.ucWave1);
52             this.Name = "UCProcessWave";
53             this.Size = new System.Drawing.Size(150, 150);
54             this.ResumeLayout(false);
55
56         }
57
58         #endregion
59
60         private UCWave ucWave1;
61     }
62 }

最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧

原文地址:https://www.cnblogs.com/bfyx/p/11399183.html

时间: 2024-10-04 07:34:17

(四十六)c#Winform自定义控件-水波进度条的相关文章

Android实战简易教程-第四十六枪(自定义控件体验之罗盘)

前言 作为一名有创新意思的开发人员,你迟早会发现内置的控件会满足不了你的想象力. 拥有扩展已存在的视图.组建复合的控件以及创建独特的新视图能力,可以创建出最适合自己应用程序工作流的有优美用户界面,让用户得到最优的体验. 创建新视图的最佳方法和希望达到的目标有关: 1.如果现有控件已经可以满足希望实现的基本功能,那么只需对现有控件的外观或行为进行修改或扩展即可.通过重写事件处理程序和onDraw()方法. 2.可以通过组合多个视图来创建不可分割的.可重用的控件,从而使它可以综合使用过个相关联的视图

NeHe OpenGL教程 第四十六课:全屏反走样

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第四十六课:全屏反走样 全屏反走样 当今显卡的强大功能,你几乎什么都不用做,只需要在创建窗口的时候该一个数据.看看吧,驱动程序为你做完了一切. 在图形的绘制中,直线的走样是非常影响美观的,我们可以使用反走样解决这个问题.在众多的解决

四十六、android中的Bitmap

四十六.android中的Bitmap: http://www.cnblogs.com/linjiqin/archive/2011/12/28/2304940.html 四十七.实现调用Android手机的拍照功能: http://www.cnblogs.com/linjiqin/archive/2011/12/28/2304970.html

ActionScript3游戏中的图像编程(连载四十六)

总目录:http://blog.csdn.net/iloveas2014/article/details/38304477 3.1.2 以小见大--从细节损失洞悉滤镜本质 把它再改回内斜角,边缘似乎光滑了些,但这种错觉仅仅是由于阴影与蓝色的对比度不够强烈,才会让边缘的粗糙不够显眼.把文字颜色调成浅紫以后,转角处的锯齿依旧一览无余.(图 3.6),而Photoshop应用同样的设置则不会出现同样的问题(图 3.7). 图 3.6 模糊值为3的内侧斜角滤镜 图 3.7 大小等于3的斜面样式 如果认为

QT开发(四十六)——QT数据库编程基础

QT开发(四十六)--QT数据库编程基础 一.Qt SQL模块简介 1.Qt SQL模块简介 QT通过Qt SQL模块提供了对SQL数据库的支持,Qt SQL模块中的API分为三层:驱动层.SQL接口层.用户接口层. 如果要使用Qt SQL模块中的类,需要在工程文件(.pro文件)中添加QT += sql代码. 2.驱动层 驱动层为具体的数据库和SQL接口层之间提供了底层的桥梁,主要类包括Qt SQL模块中的QSqlDriver.QSqlDriverCreator.QSqlDriverCreat

【Unity 3D】学习笔记四十六:输入与控制——键盘事件

在游戏中,玩家控制主角移动,按键攻击,选择行走.都需要在程序中监听玩家的输入.unity为开发者提供了input库,来支持键盘事件,鼠标事件以及触摸事件.本文主要回顾键盘事件,以后会逐文复习鼠标以及触摸事件. 键盘事件 一般的PC键盘有104个不同的按键,在程序中通过监听这些按键事件,从而进一步执行逻辑操作.如:射击游戏中,W表示前进,S表示后退,A表示左移,D表示右移. 按下事件 在脚本中,用input.GetKeyDown( )方法将按键值作为参数,监听此按键是否被按下.按下返回true,否

程序员的奋斗史(四十六)——大学断代史(十)——给学弟学妹们的忠告——终结篇

文/温国兵 「写在前面」 大学断代史终于要完结了,就像一条再长的路总有终点一样.该系列文章前前后后写了一两个月,也该收尾了,至于收尾的文章,想了想,决定写写自己对学弟学妹的忠告.本篇文章以话题的形式呈现. 「关于专业」 我相信大多数的读者在高考填志愿都不知道软件工程或者计算机专业是做啥的,稀里糊涂就踏上了这条IT不归路.身处小乡村,消息相对闭塞,能使用电脑都是奢侈的事情,这就是当初我高考后的境况,相信现在有很大的改变.如果你对IT行业抱有一番热情,恭喜你,选对了好专业,好好学,今后的路错不了.如

“全栈2019”Java多线程第四十六章:判断任意线程是否已持有写锁

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第四十六章:判断任意线程是否已持有写锁 下一章 "全栈2019"Java多线程第四十七章:判断锁是否为公平锁isFair() 学习小组 加入同步学习小组,共同交流与进步. 方式一:加入编程圈子. 方式二:关注头条号Gorhaf,私信"Java学习小组". 方式三:关

第四十六章

第四十六章1 马应该种田,不应该打仗:你应该工作,不应该总想买买买 天下有道,却走马以粪.天下无道,戎马生于郊. 天下有道的时候,马都在田里耕地,天下无道的时候,马都在战场打仗. 要放低欲望,把资源用在正地方. 各位朋友大家好,清晨起来,我们接着来讲<道德经>,看看老子老先生带给我们什么样人生启发.我在今天起床之前做梦,梦是让人黯然神伤的,我做梦梦见自己给一帮孩子妈妈,带着小朋友讲课,就讲这个“道”,结果妈妈不听,在下面聊天,孩子哭闹,乱作一团,大家说讲点感冒吧,讲“道”有什么用,我说“道”很