C#自定义控件学习1:基类控件-HZHControls

本文介绍了大神冰封一夏的开源控件库HZHControls,详细讲解了如何创建基类控件,包括圆角、边框和填充颜色等功能,并提供了属性和事件的设置。通过步骤指导,演示了从新建项目到生成基类控件库的过程,同时给出了源代码示例。最后,展示了基类控件的调用效果和下载链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  大神冰封一夏的开源套件HZHControls很漂亮,值得学习。跟着大神的足迹走一遍,肯定能学到不少。

一、基类

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

二、基类控件

1、主要实现功能:

  • 圆角
  • 边框
  • 填充颜色

2、属性

  包含圆角角度,边框颜色,边框宽度,填充颜色,背景色等

3、事件

  需要重写OnPaint,来画边框以及填充颜色。

三、基类控件的设计

  步骤如下:

  • 1.点击文件->新建项目->选择Windows控件库,命名Ky_Controls
  • 2.系统会自动生成Ky_Controls.cs,删掉吧。
  • 3.添加新建文件夹,重命名Controls。
  • 4.右击文件夹Controls,添加新建项,选择“类”,把大神的程序粘过来。
  • 5.点击生成->生成 项目名称 ,完成这一步后会在bin或debug目录下看到"Ky_Controls.dll"文件,这个便是基类控件库了。

四、源程序

1、UserControl.cs 基类控件

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace Ky_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);
            }
        }

    }
}

2、UCControlBase.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Ky_Controls.Controls
{
    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
    }
}

五、基类控件的调用

添加自定义控件后在这个位置

  写了一个调用测试文件,运行后长这样。
就是一个圆角边框的面板

六、源程序下载

大龙10的下载https://download.youkuaiyun.com/download/dalong10/20366998

七、参考资料

1、冰封一夏的博客https://www.cnblogs.com/bfyx/p/11361809.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值