1. 程式人生 > >(一)c#Winform自定義控制元件-基類控制元件

(一)c#Winform自定義控制元件-基類控制元件

前提

入行已經7,8年了,一直想做一套漂亮點的自定義控制元件,於是就有了本系列文章。

開源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control

如果覺得寫的還行,請點個 star 支援一下吧

歡迎前來交流探討: 企鵝群568015492 

準備工作

自定義的分為控制元件和窗體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 點個星星吧