入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
https://www.cnblogs.com/bfyx/p/11364884.html
自定义的分为控件和窗体2种类型,分别都有一个基类,基类实现公共的大部分工作
首先从基类控件开始吧,
主要实现功能:
添加一个用户控件,命名为UCControlBase,写入相关属性,包含圆角角度,边框颜色,边框宽度,填充颜色,背景色等
1 private bool _isRadius = false;
2
3 private int _cornerRadius = 24;
4
5
6 private bool _isShowRect = false;
7
8 private Color _rectColor = Color.FromArgb(220, 220, 220);
9
10 private int _rectWidth = 1;
11
12 private Color _fillColor = Color.Transparent;
13 /// <summary>
14 /// 是否圆角
15 /// </summary>
16 [Description("是否圆角"), Category("自定义")]
17 public bool IsRadius
18 {
19 get
20 {
21 return this._isRadius;
22 }
23 set
24 {
25 this._isRadius = value;
26 }
27 }
28 //圆角角度
29 [Description("圆角角度"), Category("自定义")]
30 public int ConerRadius
31 {
32 get
33 {
34 return this._cornerRadius;
35 }
36 set
37 {
38 this._cornerRadius = value;
39 }
40 }
41
42 /// <summary>
43 /// 是否显示边框
44 /// </summary>
45 [Description("是否显示边框"), Category("自定义")]
46 public bool IsShowRect
47 {
48 get
49 {
50 return this._isShowRect;
51 }
52 set
53 {
54 this._isShowRect = value;
55 }
56 }
57 /// <summary>
58 /// 边框颜色
59 /// </summary>
60 [Description("边框颜色"), Category("自定义")]
61 public Color RectColor
62 {
63 get
64 {
65 return this._rectColor;
66 }
67 set
68 {
69 this._rectColor = value;
70 this.Refresh();
71 }
72 }
73 /// <summary>
74 /// 边框宽度
75 /// </summary>
76 [Description("边框宽度"), Category("自定义")]
77 public int RectWidth
78 {
79 get
80 {
81 return this._rectWidth;
82 }
83 set
84 {
85 this._rectWidth = value;
86 }
87 }
88 /// <summary>
89 /// 当使用边框时填充颜色,当值为背景色或透明色或空值则不填充
90 /// </summary>
91 [Description("当使用边框时填充颜色,当值为背景色或透明色或空值则不填充"), Category("自定义")]
92 public Color FillColor
93 {
94 get
95 {
96 return this._fillColor;
97 }
98 set
99 {
100 this._fillColor = value;
101 }
102 }
需要做的就是重写OnPaint,来画边框以及填充颜色
1 protected override void OnPaint(PaintEventArgs e)
2 {
3 if (this.Visible)
4 {
5 if (this._isRadius)
6 {
7 this.SetWindowRegion();
8 }
9 if (this._isShowRect)
10 {
11 Color rectColor = this._rectColor;
12 Pen pen = new Pen(rectColor, (float)this._rectWidth);
13 Rectangle clientRectangle = base.ClientRectangle;
14 GraphicsPath graphicsPath = new GraphicsPath();
15 graphicsPath.AddArc(0, 0, _cornerRadius, _cornerRadius, 180f, 90f);
16 graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - 1, 0, _cornerRadius, _cornerRadius, 270f, 90f);
17 graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - 1, clientRectangle.Height - _cornerRadius - 1, _cornerRadius, _cornerRadius, 0f, 90f);
18 graphicsPath.AddArc(0, clientRectangle.Height - _cornerRadius - 1, _cornerRadius, _cornerRadius, 90f, 90f);
19 graphicsPath.CloseFigure();
20 e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
21 if (_fillColor != Color.Empty && _fillColor != Color.Transparent && _fillColor != this.BackColor)
22 e.Graphics.FillPath(new SolidBrush(this._fillColor), graphicsPath);
23 e.Graphics.DrawPath(pen, graphicsPath);
24 }
25 }
26 base.OnPaint(e);
27 }
28
29 private void SetWindowRegion()
30 {
31 GraphicsPath path = new GraphicsPath();
32 Rectangle rect = new Rectangle(-1, -1, base.Width + 1, base.Height);
33 path = this.GetRoundedRectPath(rect, this._cornerRadius);
34 base.Region = new Region(path);
35 }
36
37 private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
38 {
39 Rectangle rect2 = new Rectangle(rect.Location, new Size(radius, radius));
40 GraphicsPath graphicsPath = new GraphicsPath();
41 graphicsPath.AddArc(rect2, 180f, 90f);//左上角
42 rect2.X = rect.Right - radius;
43 graphicsPath.AddArc(rect2, 270f, 90f);//右上角
44 rect2.Y = rect.Bottom - radius;
45 rect2.Width += 1;
46 rect2.Height += 1;
47 graphicsPath.AddArc(rect2, 360f, 90f);//右下角
48 rect2.X = rect.Left;
49 graphicsPath.AddArc(rect2, 90f, 90f);//左下角
50 graphicsPath.CloseFigure();
51 return graphicsPath;
52 }
至此基类控件就完成了,下面是完成代码
1 // 版权所有 黄正辉 交流群:568015492 QQ:623128629
2 // 文件名称:UCControlBase.cs
3 // 创建日期:2019-08-15 16:04:12
4 // 功能描述:ControlBase
5 // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
6 using System;
7 using System.Collections.Generic;
8 using System.ComponentModel;
9 using System.Drawing;
10 using System.Data;
11 using System.Linq;
12 using System.Text;
13 using System.Windows.Forms;
14 using System.Drawing.Drawing2D;
15
16 namespace HZH_Controls.Controls
17 {
18 [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(System.ComponentModel.Design.IDesigner))]
19 public partial class UCControlBase : UserControl, IContainerControl
20 {
21 private bool _isRadius = false;
22
23 private int _cornerRadius = 24;
24
25
26 private bool _isShowRect = false;
27
28 private Color _rectColor = Color.FromArgb(220, 220, 220);
29
30 private int _rectWidth = 1;
31
32 private Color _fillColor = Color.Transparent;
33 /// <summary>
34 /// 是否圆角
35 /// </summary>
36 [Description("是否圆角"), Category("自定义")]
37 public bool IsRadius
38 {
39 get
40 {
41 return this._isRadius;
42 }
43 set
44 {
45 this._isRadius = value;
46 }
47 }
48 //圆角角度
49 [Description("圆角角度"), Category("自定义")]
50 public int ConerRadius
51 {
52 get
53 {
54 return this._cornerRadius;
55 }
56 set
57 {
58 this._cornerRadius = value;
59 }
60 }
61
62 /// <summary>
63 /// 是否显示边框
64 /// </summary>
65 [Description("是否显示边框"), Category("自定义")]
66 public bool IsShowRect
67 {
68 get
69 {
70 return this._isShowRect;
71 }
72 set
73 {
74 this._isShowRect = value;
75 }
76 }
77 /// <summary>
78 /// 边框颜色
79 /// </summary>
80 [Description("边框颜色"), Category("自定义")]
81 public Color RectColor
82 {
83 get
84 {
85 return this._rectColor;
86 }
87 set
88 {
89 this._rectColor = value;
90 this.Refresh();
91 }
92 }
93 /// <summary>
94 /// 边框宽度
95 /// </summary>
96 [Description("边框宽度"), Category("自定义")]
97 public int RectWidth
98 {
99 get
100 {
101 return this._rectWidth;
102 }
103 set
104 {
105 this._rectWidth = value;
106 }
107 }
108 /// <summary>
109 /// 当使用边框时填充颜色,当值为背景色或透明色或空值则不填充
110 /// </summary>
111 [Description("当使用边框时填充颜色,当值为背景色或透明色或空值则不填充"), Category("自定义")]
112 public Color FillColor
113 {
114 get
115 {
116 return this._fillColor;
117 }
118 set
119 {
120 this._fillColor = value;
121 }
122 }
123
124 public UCControlBase()
125 {
126 this.InitializeComponent();
127 base.SetStyle(ControlStyles.UserPaint, true);
128 base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
129 base.SetStyle(ControlStyles.DoubleBuffer, true);
130 }
131
132 protected override void OnPaint(PaintEventArgs e)
133 {
134 if (this.Visible)
135 {
136 if (this._isRadius)
137 {
138 this.SetWindowRegion();
139 }
140 if (this._isShowRect)
141 {
142 Color rectColor = this._rectColor;
143 Pen pen = new Pen(rectColor, (float)this._rectWidth);
144 Rectangle clientRectangle = base.ClientRectangle;
145 GraphicsPath graphicsPath = new GraphicsPath();
146 graphicsPath.AddArc(0, 0, _cornerRadius, _cornerRadius, 180f, 90f);
147 graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - 1, 0, _cornerRadius, _cornerRadius, 270f, 90f);
148 graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - 1, clientRectangle.Height - _cornerRadius - 1, _cornerRadius, _cornerRadius, 0f, 90f);
149 graphicsPath.AddArc(0, clientRectangle.Height - _cornerRadius - 1, _cornerRadius, _cornerRadius, 90f, 90f);
150 graphicsPath.CloseFigure();
151 e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
152 if (_fillColor != Color.Empty && _fillColor != Color.Transparent && _fillColor != this.BackColor)
153 e.Graphics.FillPath(new SolidBrush(this._fillColor), graphicsPath);
154 e.Graphics.DrawPath(pen, graphicsPath);
155 }
156 }
157 base.OnPaint(e);
158 }
159
160 private void SetWindowRegion()
161 {
162 GraphicsPath path = new GraphicsPath();
163 Rectangle rect = new Rectangle(-1, -1, base.Width + 1, base.Height);
164 path = this.GetRoundedRectPath(rect, this._cornerRadius);
165 base.Region = new Region(path);
166 }
167
168 private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
169 {
170 Rectangle rect2 = new Rectangle(rect.Location, new Size(radius, radius));
171 GraphicsPath graphicsPath = new GraphicsPath();
172 graphicsPath.AddArc(rect2, 180f, 90f);//左上角
173 rect2.X = rect.Right - radius;
174 graphicsPath.AddArc(rect2, 270f, 90f);//右上角
175 rect2.Y = rect.Bottom - radius;
176 rect2.Width += 1;
177 rect2.Height += 1;
178 graphicsPath.AddArc(rect2, 360f, 90f);//右下角
179 rect2.X = rect.Left;
180 graphicsPath.AddArc(rect2, 90f, 90f);//左下角
181 graphicsPath.CloseFigure();
182 return graphicsPath;
183 }
184
185 protected override void WndProc(ref Message m)
186 {
187 if (m.Msg != 20)
188 {
189 base.WndProc(ref m);
190 }
191 }
192
193
194 }
195 }
1 partial class UCControlBase
2 {
3 /// <summary>
4 /// 必需的设计器变量。
5 /// </summary>
6 private System.ComponentModel.IContainer components = null;
7
8 /// <summary>
9 /// 清理所有正在使用的资源。
10 /// </summary>
11 /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
12 protected override void Dispose(bool disposing)
13 {
14 if (disposing && (components != null))
15 {
16 components.Dispose();
17 }
18 base.Dispose(disposing);
19 }
20
21 #region 组件设计器生成的代码
22
23 /// <summary>
24 /// 设计器支持所需的方法 - 不要
25 /// 使用代码编辑器修改此方法的内容。
26 /// </summary>
27 private void InitializeComponent()
28 {
29 components = new System.ComponentModel.Container();
30 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
31 base.SuspendLayout();
32 base.AutoScaleDimensions = new SizeF(9f, 20f);
33 base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
34 this.DoubleBuffered = true;
35 this.Font = new Font("微软雅黑", 15f, FontStyle.Regular, GraphicsUnit.Pixel);
36 base.Margin = new Padding(4, 5, 4, 5);
37 base.Name = "UCBase";
38 base.Size = new Size(237, 154);
39 base.ResumeLayout(false);
40 }
41
42 #endregion
43 }
用处:你可以把它当作一个panel来用,比如需要包裹一些控件并显示一个圆角边框的时候,你应该想到用这个控件
效果图:其实就是一个圆角边框的面板
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧