­

(一)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 點個星星吧