前提

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

开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
<https://gitee.com/kwwwvagaa/net_winform_custom_control>

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

欢迎前来交流探讨: 企鹅群568015492 
<https://shang.qq.com/wpa/qunwpa?idkey=6e08741ef16fe53bf0314c1c9e336c4f626047943a8b76bac062361bab6b4f8d>

目录

https://www.cnblogs.com/bfyx/p/11364884.html
<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 } View Code 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 } View
Code
用处及效果

用处:你可以把它当作一个panel来用,比如需要包裹一些控件并显示一个圆角边框的时候,你应该想到用这个控件

效果图:其实就是一个圆角边框的面板



 

最后的话

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

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信