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

  • 2019 年 10 月 3 日
  • 笔记

前提

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

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

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

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

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

目录

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

准备工作

自定义的分为控件和窗体2种类型,分别都有一个基类,基类实现公共的大部分工作

开始

首先从基类控件开始吧,

主要实现功能:

  1. 圆角
  2. 边框
  3. 填充颜色

添加一个用户控件,命名为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 点个星星吧