『7x24小时有问必答』
C# 中实现自定义按钮控件,用于替代 WinForms 默认按钮,实现个性化样式(如圆角、渐变、悬停 / 点击效果)并保证高可复用性,本文将提供完整的实现方案,包括自定义控件核心代码、使用方法及扩展特性。

一、核心思路

自定义按钮的核心是继承Button基类(复用按钮原有交互逻辑,如点击事件、焦点状态等),通过重写OnPaint方法实现个性化绘制,同时暴露可自定义属性(圆角、颜色、渐变等),支持设计时编辑和运行时动态修改,满足不同 UI 风格需求。

二、完整实现代码

1. 自定义按钮控件(CustomStyleButton.cs)

using  System;using  System.Drawing;using  System.Drawing.Drawing2D;using  System.Windows.Forms;using  System.ComponentModel;namespace  CustomControls{       ///  <summary>       ///  自定义样式按钮控件       ///  支持圆角、渐变背景、悬停/点击状态切换、自定义文字颜色       ///  </summary>       public  class  CustomStyleButton  :  Button      {             #region  私有字段             // 圆角半径(默认10px)             private  int  _cornerRadius =  10;             // 渐变起始颜色(默认浅蓝色)             private  Color _gradientStartColor = Color.LightSkyBlue;             // 渐变结束颜色(默认深蓝色)             private  Color _gradientEndColor = Color.RoyalBlue;             // 悬停状态渐变起始颜色             private  Color _hoverStartColor = Color.LightBlue;             // 悬停状态渐变结束颜色             private  Color _hoverEndColor = Color.DodgerBlue;             // 点击状态渐变起始颜色             private  Color _pressedStartColor = Color.SkyBlue;             // 点击状态渐变结束颜色             private  Color _pressedEndColor = Color.Blue;             // 按钮文字颜色(默认白色)             private  Color _buttonTextColor = Color.White;             #endregion             #region  公共属性(支持设计时编辑)             ///  <summary>             ///  按钮圆角半径             ///  </summary>            [Description("按钮圆角半径(值越大圆角越明显)"), Category("自定义按钮样式")]             public  int  CornerRadius            {                   get  => _cornerRadius;                   set                  {                        _cornerRadius = Math.Max(0,  value);  // 防止负数                        Invalidate();  // 属性变更时重绘控件                  }            }             ///  <summary>             ///  正常状态渐变起始颜色             ///  </summary>            [Description("正常状态下渐变起始颜色"), Category("自定义按钮样式")]             public  Color GradientStartColor            {                   get  => _gradientStartColor;                   set                  {                        _gradientStartColor =  value;                        Invalidate();                  }            }             ///  <summary>             ///  正常状态渐变结束颜色             ///  </summary>            [Description("正常状态下渐变结束颜色"), Category("自定义按钮样式")]             public  Color GradientEndColor            {                   get  => _gradientEndColor;                   set                  {                        _gradientEndColor =  value;                        Invalidate();                  }            }             ///  <summary>             ///  鼠标悬停状态渐变起始颜色             ///  </summary>            [Description("鼠标悬停时渐变起始颜色"), Category("自定义按钮样式")]             public  Color HoverStartColor            {                   get  => _hoverStartColor;                   set                  {                        _hoverStartColor =  value;                        Invalidate();                  }            }             ///  <summary>             ///  鼠标悬停状态渐变结束颜色             ///  </summary>            [Description("鼠标悬停时渐变结束颜色"), Category("自定义按钮样式")]             public  Color HoverEndColor            {                   get  => _hoverEndColor;                   set                  {                        _hoverEndColor =  value;                        Invalidate();                  }            }             ///  <summary>             ///  鼠标点击状态渐变起始颜色             ///  </summary>            [Description("鼠标点击时渐变起始颜色"), Category("自定义按钮样式")]             public  Color PressedStartColor            {                   get  => _pressedStartColor;                   set                  {                        _pressedStartColor =  value;                        Invalidate();                  }            }             ///  <summary>             ///  鼠标点击状态渐变结束颜色             ///  </summary>            [Description("鼠标点击时渐变结束颜色"), Category("自定义按钮样式")]             public  Color PressedEndColor            {                   get  => _pressedEndColor;                   set                  {                        _pressedEndColor =  value;                        Invalidate();                  }            }             ///  <summary>             ///  按钮文字颜色             ///  </summary>            [Description("按钮显示文字的颜色"), Category("自定义按钮样式")]             public  Color ButtonTextColor            {                   get  => _buttonTextColor;                   set                  {                        _buttonTextColor =  value;                        Invalidate();                  }            }             #endregion             #region  构造函数             public  CustomStyleButton()            {                   // 初始化按钮基础样式                   this.FlatStyle = FlatStyle.Flat;  // 隐藏默认边框和样式                   this.FlatAppearance.BorderSize =  0;  // 移除默认边框                   this.SetStyle(ControlStyles.AllPaintingInWmPaint |                                         ControlStyles.OptimizedDoubleBuffer |                                         ControlStyles.ResizeRedraw |                                         ControlStyles.UserPaint,  true);  // 开启双缓冲,防止闪烁                   this.DoubleBuffered =  true;                   this.Font =  new  Font("微软雅黑",  9F, FontStyle.Regular, GraphicsUnit.Point);  // 默认字体            }             #endregion             #region  核心重写方法:OnPaint(绘制自定义按钮样式)             ///  <summary>             ///  重写OnPaint方法,实现自定义按钮的绘制逻辑             ///  </summary>             ///  <param name="e">绘图事件参数             protected  override  void  OnPaint(PaintEventArgs e)            {                   base.OnPaint(e);                  Graphics g = e.Graphics;                  g.SmoothingMode = SmoothingMode.AntiAlias;  // 开启抗锯齿,使圆角和文字更平滑                  g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;  // 文字高清渲染                   // 1. 定义按钮绘制区域(排除内边距,适配按钮大小)                  Rectangle buttonRect =  new  Rectangle(0,  0,  this.Width -  1,  this.Height -  1);                   // 2. 创建圆角路径(核心:实现圆角按钮)                   using  (GraphicsPath buttonPath =  new  GraphicsPath())                  {                         // 添加圆角矩形到路径(四个角统一圆角半径)                        buttonPath.AddArc(buttonRect.X, buttonRect.Y, _cornerRadius, _cornerRadius,  180,  90);  // 左上角                        buttonPath.AddArc(buttonRect.Right - _cornerRadius, buttonRect.Y, _cornerRadius, _cornerRadius,  270,  90);  // 右上角                        buttonPath.AddArc(buttonRect.Right - _cornerRadius, buttonRect.Bottom - _cornerRadius, _cornerRadius, _cornerRadius,  0,  90);  // 右下角                        buttonPath.AddArc(buttonRect.X, buttonRect.Bottom - _cornerRadius, _cornerRadius, _cornerRadius,  90,  90);  // 左下角                        buttonPath.CloseAllFigures();  // 闭合路径                         // 3. 根据按钮状态选择对应的渐变颜色                        LinearGradientBrush gradientBrush =  null;                         if  (this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)) &&  this.MouseButtons == MouseButtons.Left)                        {                               // 状态1:鼠标点击(按住)                              gradientBrush =  new  LinearGradientBrush(buttonRect, _pressedStartColor, _pressedEndColor, LinearGradientMode.Vertical);                        }                         else  if  (this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)))                        {                               // 状态2:鼠标悬停                              gradientBrush =  new  LinearGradientBrush(buttonRect, _hoverStartColor, _hoverEndColor, LinearGradientMode.Vertical);                        }                         else                        {                               // 状态3:正常状态(无交互)                              gradientBrush =  new  LinearGradientBrush(buttonRect, _gradientStartColor, _gradientEndColor, LinearGradientMode.Vertical);                        }                         // 4. 绘制按钮背景(渐变+圆角)                         using  (gradientBrush)                        {                              g.FillPath(gradientBrush, buttonPath);                        }                         // 5. 绘制按钮边框(增强质感,半透明黑色)                         using  (Pen borderPen =  new  Pen(Color.FromArgb(50, Color.Black),  1))                        {                              g.DrawPath(borderPen, buttonPath);                        }                         // 6. 绘制按钮文字(居中显示)                         using  (SolidBrush textBrush =  new  SolidBrush(_buttonTextColor))                        {                               // 文字居中布局                              StringFormat stringFormat =  new  StringFormat                              {                                    Alignment = StringAlignment.Center,                                    LineAlignment = StringAlignment.Center                              };                              g.DrawString(this.Text,  this.Font, textBrush, buttonRect, stringFormat);                        }                  }            }             #endregion      }}

三、控件使用方法

步骤 1:添加控件到窗体

将上述代码编译为类库(或直接放在 WinForms 项目中)
在 Visual Studio 工具箱中,右键→「选择项」→「浏览」→ 选中编译后的程序集,确认后CustomStyleButton会出现在工具箱中
直接拖拽CustomStyleButton到 WinForms 窗体上,可自由调整按钮大小

步骤 2:使用方式(设计时 + 运行时)

1. 设计时配置(可视化操作)

选中窗体上的CustomStyleButton,在「属性」窗口中找到「自定义按钮样式」分类,可直接修改:
圆角半径(CornerRadius
各状态渐变颜色(正常 / 悬停 / 点击)
文字颜色(ButtonTextColor
文字内容(Text)、字体(Font)等基础属性

2. 运行时动态修改(代码控制)

using  System;using  System.Drawing;using  System.Windows.Forms;using  CustomControls;namespace  CustomButtonDemo{       public  partial  class  FrmMain  :  Form      {             public  FrmMain()            {                  InitializeComponent();            }             // 示例1:动态修改按钮样式             private  void  btnSetStyle_Click(object  sender, EventArgs e)            {                   // 修改圆角半径为20                  customStyleButton1.CornerRadius =  20;                   // 修改正常状态渐变颜色(红→深红)                  customStyleButton1.GradientStartColor = Color.LightCoral;                  customStyleButton1.GradientEndColor = Color.DarkRed;                   // 修改文字颜色为黄色                  customStyleButton1.ButtonTextColor = Color.Yellow;            }             // 示例2:动态修改按钮文字             private  void  btnSetText_Click(object  sender, EventArgs e)            {                  customStyleButton1.Text =  "动态修改的按钮文字";            }             // 示例3:绑定按钮点击事件(与默认Button用法一致)             private  void  customStyleButton1_Click(object  sender, EventArgs e)            {                  MessageBox.Show("自定义按钮被点击了!");            }      }}

四、关键特性说明

核心继承
:直接继承System.Windows.Forms.Button,完全复用默认按钮的所有交互逻辑(点击事件、焦点、禁用状态等),无需额外封装事件
个性化样式
圆角效果:通过GraphicsPath绘制圆角矩形,圆角半径可自定义
渐变背景:支持垂直渐变,正常 / 悬停 / 点击三种状态分别对应独立渐变颜色
高清渲染:开启抗锯齿和文字高清渲染,样式更细腻
状态切换
:自动识别鼠标「正常」「悬停」「点击」三种状态,自动切换样式,无需手动处理鼠标事件
设计时支持
:通过[Description][Category]特性,属性可在 VS 属性窗口中分类显示,可视化配置更便捷
无闪烁
:开启双缓冲和优化绘制样式,避免控件重绘时出现闪烁问题
高可复用性
:一次封装,可在多个项目中拖拽使用,支持动态修改样式
五、源码获取方式:公众号输入:【自定义按钮】

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码