前提
入行已经 7,8 年了, 一直想做一套漂亮点的自定义控件, 于是就有了本系列文章.
开源地址:
如果觉得写的还行, 请点个 star 支持一下吧
准备工作
自定义的分为控件和窗体 2 种类型, 分别都有一个基类, 基类实现公共的大部分工作
开始
首先从基类控件开始吧,
主要实现功能:
圆角
边框
填充颜色
添加一个用户控件, 命名为 UCControlBase, 写入相关属性, 包含圆角角度, 边框颜色, 边框宽度, 填充颜色, 背景色等
- private bool _isRadius = false;
- private int _cornerRadius = 24;
- private bool _isShowRect = false;
- private Color _rectColor = Color.FromArgb(220, 220, 220);
- private int _rectWidth = 1;
- private Color _fillColor = Color.Transparent;
- /// <summary>
- /// 是否圆角
- /// </summary>
- [Description("是否圆角"), Category("自定义")]
- public bool IsRadius
- {
- get
- {
- return this._isRadius;
- }
- set
- {
- this._isRadius = value;
- }
- }
- // 圆角角度
- [Description("圆角角度"), Category("自定义")]
- public int ConerRadius
- {
- get
- {
- return this._cornerRadius;
- }
- set
- {
- this._cornerRadius = value;
- }
- }
- /// <summary>
- /// 是否显示边框
- /// </summary>
- [Description("是否显示边框"), Category("自定义")]
- public bool IsShowRect
- {
- get
- {
- return this._isShowRect;
- }
- set
- {
- this._isShowRect = value;
- }
- }
- /// <summary>
- /// 边框颜色
- /// </summary>
- [Description("边框颜色"), Category("自定义")]
- public Color RectColor
- {
- get
- {
- return this._rectColor;
- }
- set
- {
- this._rectColor = value;
- this.Refresh();
- }
- }
- /// <summary>
- /// 边框宽度
- /// </summary>
- [Description("边框宽度"), Category("自定义")]
- public int RectWidth
- {
- get
- {
- return this._rectWidth;
- }
- set
- {
- this._rectWidth = value;
- }
- }
- /// <summary>
- /// 当使用边框时填充颜色, 当值为背景色或透明色或空值则不填充
- /// </summary>
- [Description("当使用边框时填充颜色, 当值为背景色或透明色或空值则不填充"), Category("自定义")]
- public Color FillColor
- {
- get
- {
- return this._fillColor;
- }
- set
- {
- this._fillColor = value;
- }
- }
需要做的就是重写 OnPaint, 来画边框以及填充颜色
- protected override void OnPaint(PaintEventArgs e)
- {
- if (this.Visible)
- {
- if (this._isRadius)
- {
- this.SetWindowRegion();
- }
- if (this._isShowRect)
- {
- Color rectColor = this._rectColor;
- Pen pen = new Pen(rectColor, (float)this._rectWidth);
- Rectangle clientRectangle = base.ClientRectangle;
- GraphicsPath graphicsPath = new GraphicsPath();
- graphicsPath.AddArc(0, 0, _cornerRadius, _cornerRadius, 180f, 90f);
- graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - 1, 0, _cornerRadius, _cornerRadius, 270f, 90f);
- graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - 1, clientRectangle.Height - _cornerRadius - 1, _cornerRadius, _cornerRadius, 0f, 90f);
- graphicsPath.AddArc(0, clientRectangle.Height - _cornerRadius - 1, _cornerRadius, _cornerRadius, 90f, 90f);
- graphicsPath.CloseFigure();
- e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
- if (_fillColor != Color.Empty && _fillColor != Color.Transparent && _fillColor != this.BackColor)
- e.Graphics.FillPath(new SolidBrush(this._fillColor), graphicsPath);
- e.Graphics.DrawPath(pen, graphicsPath);
- }
- }
- base.OnPaint(e);
- }
- private void SetWindowRegion()
- {
- GraphicsPath path = new GraphicsPath();
- Rectangle rect = new Rectangle(-1, -1, base.Width + 1, base.Height);
- path = this.GetRoundedRectPath(rect, this._cornerRadius);
- base.Region = new Region(path);
- }
- private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
- {
- Rectangle rect2 = new Rectangle(rect.Location, new Size(radius, radius));
- GraphicsPath graphicsPath = new GraphicsPath();
- graphicsPath.AddArc(rect2, 180f, 90f);// 左上角
- rect2.X = rect.Right - radius;
- graphicsPath.AddArc(rect2, 270f, 90f);// 右上角
- rect2.Y = rect.Bottom - radius;
- rect2.Width += 1;
- rect2.Height += 1;
- graphicsPath.AddArc(rect2, 360f, 90f);// 右下角
- rect2.X = rect.Left;
- graphicsPath.AddArc(rect2, 90f, 90f);// 左下角
- graphicsPath.CloseFigure();
- return graphicsPath;
- }
至此基类控件就完成了, 下面是完成代码
- // 版权所有 黄正辉 交流群: 568015492 QQ:623128629
- // 文件名称: UCControlBase.cs
- // 创建日期: 2019-08-15 16:04:12
- // 功能描述: ControlBase
- // 项目地址: https://gitee.com/kwwwvagaa/net_winform_custom_control
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.Data;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- using System.Drawing.Drawing2D;
- namespace HZH_Controls.Controls
- {
- [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(System.ComponentModel.Design.IDesigner))]
- public partial class UCControlBase : UserControl, IContainerControl
- {
- private bool _isRadius = false;
- private int _cornerRadius = 24;
- private bool _isShowRect = false;
- private Color _rectColor = Color.FromArgb(220, 220, 220);
- private int _rectWidth = 1;
- private Color _fillColor = Color.Transparent;
- /// <summary>
- /// 是否圆角
- /// </summary>
- [Description("是否圆角"), Category("自定义")]
- public bool IsRadius
- {
- get
- {
- return this._isRadius;
- }
- set
- {
- this._isRadius = value;
- }
- }
- // 圆角角度
- [Description("圆角角度"), Category("自定义")]
- public int ConerRadius
- {
- get
- {
- return this._cornerRadius;
- }
- set
- {
- this._cornerRadius = value;
- }
- }
- /// <summary>
- /// 是否显示边框
- /// </summary>
- [Description("是否显示边框"), Category("自定义")]
- public bool IsShowRect
- {
- get
- {
- return this._isShowRect;
- }
- set
- {
- this._isShowRect = value;
- }
- }
- /// <summary>
- /// 边框颜色
- /// </summary>
- [Description("边框颜色"), Category("自定义")]
- public Color RectColor
- {
- get
- {
- return this._rectColor;
- }
- set
- {
- this._rectColor = value;
- this.Refresh();
- }
- }
- /// <summary>
- /// 边框宽度
- /// </summary>
- [Description("边框宽度"), Category("自定义")]
- public int RectWidth
- {
- get
- {
- return this._rectWidth;
- }
- set
- {
- this._rectWidth = value;
- }
- }
- /// <summary>
- /// 当使用边框时填充颜色, 当值为背景色或透明色或空值则不填充
- /// </summary>
- [Description("当使用边框时填充颜色, 当值为背景色或透明色或空值则不填充"), Category("自定义")]
- public Color FillColor
- {
- get
- {
- return this._fillColor;
- }
- set
- {
- this._fillColor = value;
- }
- }
- public UCControlBase()
- {
- this.InitializeComponent();
- base.SetStyle(ControlStyles.UserPaint, true);
- base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
- base.SetStyle(ControlStyles.DoubleBuffer, true);
- }
- protected override void OnPaint(PaintEventArgs e)
- {
- if (this.Visible)
- {
- if (this._isRadius)
- {
- this.SetWindowRegion();
- }
- if (this._isShowRect)
- {
- Color rectColor = this._rectColor;
- Pen pen = new Pen(rectColor, (float)this._rectWidth);
- Rectangle clientRectangle = base.ClientRectangle;
- GraphicsPath graphicsPath = new GraphicsPath();
- graphicsPath.AddArc(0, 0, _cornerRadius, _cornerRadius, 180f, 90f);
- graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - 1, 0, _cornerRadius, _cornerRadius, 270f, 90f);
- graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - 1, clientRectangle.Height - _cornerRadius - 1, _cornerRadius, _cornerRadius, 0f, 90f);
- graphicsPath.AddArc(0, clientRectangle.Height - _cornerRadius - 1, _cornerRadius, _cornerRadius, 90f, 90f);
- graphicsPath.CloseFigure();
- e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
- if (_fillColor != Color.Empty && _fillColor != Color.Transparent && _fillColor != this.BackColor)
- e.Graphics.FillPath(new SolidBrush(this._fillColor), graphicsPath);
- e.Graphics.DrawPath(pen, graphicsPath);
- }
- }
- base.OnPaint(e);
- }
- private void SetWindowRegion()
- {
- GraphicsPath path = new GraphicsPath();
- Rectangle rect = new Rectangle(-1, -1, base.Width + 1, base.Height);
- path = this.GetRoundedRectPath(rect, this._cornerRadius);
- base.Region = new Region(path);
- }
- private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
- {
- Rectangle rect2 = new Rectangle(rect.Location, new Size(radius, radius));
- GraphicsPath graphicsPath = new GraphicsPath();
- graphicsPath.AddArc(rect2, 180f, 90f);// 左上角
- rect2.X = rect.Right - radius;
- graphicsPath.AddArc(rect2, 270f, 90f);// 右上角
- rect2.Y = rect.Bottom - radius;
- rect2.Width += 1;
- rect2.Height += 1;
- graphicsPath.AddArc(rect2, 360f, 90f);// 右下角
- rect2.X = rect.Left;
- graphicsPath.AddArc(rect2, 90f, 90f);// 左下角
- graphicsPath.CloseFigure();
- return graphicsPath;
- }
- protected override void WndProc(ref Message m)
- {
- if (m.Msg != 20)
- {
- base.WndProc(ref m);
- }
- }
- }
- }
- View Code
- partial class UCControlBase
- {
- /// <summary>
- /// 必需的设计器变量.
- /// </summary>
- private System.ComponentModel.IContainer components = null;
- /// <summary>
- /// 清理所有正在使用的资源.
- /// </summary>
- /// <param name="disposing"> 如果应释放托管资源, 为 true; 否则为 false.</param>
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
- #region 组件设计器生成的代码
- /// <summary>
- /// 设计器支持所需的方法 - 不要
- /// 使用代码编辑器修改此方法的内容.
- /// </summary>
- private void InitializeComponent()
- {
- components = new System.ComponentModel.Container();
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
- base.SuspendLayout();
- base.AutoScaleDimensions = new SizeF(9f, 20f);
- base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
- this.DoubleBuffered = true;
- this.Font = new Font("微软雅黑", 15f, FontStyle.Regular, GraphicsUnit.Pixel);
- base.Margin = new Padding(4, 5, 4, 5);
- base.Name = "UCBase";
- base.Size = new Size(237, 154);
- base.ResumeLayout(false);
- }
- #endregion
- }
- View Code
用处及效果
用处: 你可以把它当作一个 panel 来用, 比如需要包裹一些控件并显示一个圆角边框的时候, 你应该想到用这个控件
效果图: 其实就是一个圆角边框的面板
最后的话
如果你喜欢的话, 请到 点个星星吧
来源: https://www.cnblogs.com/bfyx/p/11361809.html