首页 > 其他分享 >Winform自定义控件与案例 - 打造炫酷的自定义开关按钮控件

Winform自定义控件与案例 - 打造炫酷的自定义开关按钮控件

时间:2025-01-13 20:30:32浏览次数:3  
标签:控件 圆角 自定义 Color Height 炫酷 90f pathZFX

文章目录


1、控件效果

在这里插入图片描述

2、开关控件需求说明

在开发 Winform 应用程序时,拥有一个美观且功能强大的 UI 控件库是非常重要的。本文将详细介绍如何使用 WinForms 创建一个带有圆角和状态切换功能的自定义开关按钮控件。我们将从头开始构建这个控件,并解决一些常见的绘制问题,如背景覆盖圆角的问题。首先,我们对开关按钮进行需求与功能拆分详解。
功能

  • 开关状态切换 点击控件,实现状态切换;
    开状态 ---- 背景色(绿色) ,右侧显示白色圆角矩形,中间有个小圆圈
    关状态 ---- 背景色(灰色) ,左侧显示白色圆角矩形,中间有个小圆圈

属性扩展

  • Checked状态
  • Checked颜色/UnChecked颜色
  • 圆角半径 Radius

事件

  • checkedChanged 属性改变时发生的

方法封装

  • 开启 Open
  • 关闭 Close

3、案例实现

1、属性扩展代码实现

代码如下(示例):

  #region 属性扩展

  /// <summary>
  /// 开关状态
  /// </summary>
  private bool checkedStatus = false;
  [DefaultValue(typeof(bool), "false"), Description("开关状态"), Category("自定义")]
  public bool CheckedStatus
  {
      get { return checkedStatus; }
      set { checkedStatus = value; Invalidate(); }
  }

  /// <summary>
  /// 圆角半径
  /// </summary>
  private int radius = 5;
  [DefaultValue(typeof(int), "5"), Description("圆角半径"), Category("自定义")]
  public int Radius
 {
     get { return radius; }
     set
     {
     //圆角半径有效性判断,不可以大于控件高度的一半
         if (value > Height / 2)
         {
             radius = Height / 2;
         }
         else
         {
             radius = value;
         }
         Invalidate();
     }
 }

  /// <summary>
  /// 状态开背景色
  /// </summary>
  private Color backGroundColorChecked = Color.Gray;
  [DefaultValue(typeof(Color), "Gray"), Description("开启时按钮背景色"), Category("自定义")]

  public Color BackGroundColorChecked
  {
      get { return backGroundColorChecked; }
      set { backGroundColorChecked = value; Invalidate(); }
  }

  /// <summary>
  /// 状态关背景色
  /// </summary>
  private Color backGroundColorUChecked = Color.Green;
  [DefaultValue(typeof(Color), "Green"), Description("关闭时按钮背景色"), Category("自定义")]

  public Color BackGroundColorUChecked
  {
      get { return backGroundColorUChecked; }
      set { backGroundColorUChecked = value; Invalidate(); }
  }

  #endregion

2、控件外观绘制

        #region 外观绘制

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;//绘图对象
                                    //g.SmoothingMode = SmoothingMode.AntiAlias;//消除锯齿
            g.SmoothingMode = SmoothingMode.HighQuality;//高质量

            //背景填充色
            Color fillColor = checkedStatus ? backGroundColorChecked : backGroundColorUChecked;
            GraphicsPath path = new GraphicsPath();//边框路径
            path = PaintHelper.GetRoundRect(rect, Radius, Radius, Radius, Radius);//生成矩形圆角形状路径
            int d = 2 * Radius;
            g.FillPath(new SolidBrush(fillColor), path);

            //白色正方形与白色圆圈---位置和状态有关
            if (CheckedStatus)
            {
                //右侧  正方形边长:Height-4  距外边框2个像素间隔
                GraphicsPath pathZFX = new GraphicsPath();//边框路径
                //左上角
                pathZFX.AddArc(Width - 1 - Height + 2, 2, d, d, 180f, 90f);
                //右上角
                pathZFX.AddArc(Width - 2 - 1 - d, 2, d, d, 270f, 90f);
                //左上角
                pathZFX.AddArc(Width - 2 - 1 - d, Height - 2 - 1 - d, d, d, 0f, 90f);
                //右上角
                pathZFX.AddArc(Width - 1 - Height + 2, Height - 2 - 1 - d, d, d, 90f, 90f);
                g.FillPath(Brushes.White, pathZFX);

                //右侧小圆 直径 (Height-4)/2
                Rectangle ellipse=new Rectangle(Width-Height+2+(Height - 4) / 4, (Height - 4) / 4, (Height - 4) / 2, (Height - 4) / 2);
                g.DrawEllipse(new Pen(fillColor,2),ellipse);

            }
            else
            {
                //左侧  正方形边长:Height-4 距外边框2个像素间隔
                GraphicsPath pathZFX = new GraphicsPath();//边框路径
                //左上角
                pathZFX.AddArc(2, 2, d, d, 180f, 90f);
                //右上角
                pathZFX.AddArc(Height - 2 - d, 2, d, d, 270f, 90f);
                //右下角
                pathZFX.AddArc(Height - 2 - d, Height - 2 - 1-d, d, d, 0f, 90f);
                //左下角
                pathZFX.AddArc(2, Height - 2 - 1 - d, d, d, 90f, 90f);
                g.FillPath(Brushes.White, pathZFX);


                //左侧小圆 直径 (Height-4)/2
                Rectangle ellipse = new Rectangle(2+ (Height - 4) / 4, (Height - 4) / 4, (Height - 4) / 2, (Height - 4) / 2);
                g.DrawEllipse(new Pen(fillColor, 2), ellipse);
            }

        }

        #endregion

3、事件实现

 #region 事件
 public event EventHandler CheckedChanged; //CheckedStatus 改变事件

 //事件触发
 protected override void OnClick(EventArgs e)
 {
     base.OnClick(e);
     CheckedStatus=!CheckedStatus;
     CheckedChanged?.Invoke(this, e);
 }

 #endregion

4、拓展方法

这里我们可以对控件的属性进行方法封装,通过调用方法实现对控件的控制,而不需要直接点击控件

 #region 拓展,方法封装
 public void Open()
 {
     CheckedStatus=true;
 }

 public void Close()
 {
     CheckedStatus = false;
 }

 #endregion

4、案例演示

请添加图片描述
通过拓展方法实现控件控制新增按钮。代码如下:

 private void button1_Click(object sender, EventArgs e)
 {
     if(!switchButton1.CheckedStatus)
     {
         switchButton1.Open();
     }
     else
     {
         switchButton1.Close();
     }
 }

运行效果如下:

请添加图片描述

通过改变按钮属性,实现不同的颜色效果

在这里插入图片描述

5、总结

通过本文的介绍,您已经学会了如何创建一个带有圆角和状态切换功能的自定义开关按钮控件。我们解决了背景覆盖圆角的问题,并提供了高质量的绘图效果。希望这些内容对您的项目有所帮助!如果您有任何问题或改进建议,请在评论区留言!欢迎分享您的想法和经验,让我们共同进步。

标签:控件,圆角,自定义,Color,Height,炫酷,90f,pathZFX
From: https://blog.csdn.net/qq_21419015/article/details/145016640

相关文章

  • Django Admin 自定义操作封装
    1.为什么需要封装?在Django开发中,我们经常需要在Admin界面添加自定义操作按钮,以便管理员执行特定的任务。通过封装,我们可以:减少重复代码统一管理自定义操作的逻辑提高代码的可维护性和可扩展性©ivwdcwso(ID:u012172506)2.CustomActionMixin的实现让我们看看C......
  • 巧用VTable打造炫酷金字塔图表
    在数据分析和可视化领域,表格是展示数据直观、有效的方式之一。今天,就让我们来探索如何利用VTable这个强大的表格组件,制作出既美观又富有信息量的金字塔图表,以及深入了解VTable中各种单元格类型的使用方法,让你的表格也能“绘”出精彩图表!用VTable实现人口金字塔 人口金字塔是......
  • 【Python】深入解析Python的上下文管理器与资源管理:实现自定义的`with`语句
    《PythonOpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门!解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界在现代编程中,资源管理的高效与安全性至关重要。Python通过上下文管理器与with语句为开发者提供了一种简洁而强大的资源管理机制。上下文管理器......
  • Qt 自定义控件(Qt绘图)
    一、QPaintEvent绘图事件1、QPaintEvent是Qt框架中一个重要的事件类,专门用于处理绘图事件。2、当Qt视图组件需要重绘自己的一部分时,就会产生QPaintEvent事件。3、Qt视图组件重绘自己,通常发生在以下情况: (1)、窗口第一次显示时:当窗口或控件第一次出现在屏幕上时,系统会生......
  • 24. 基于项的控件
    一、基于项的控件  PySide6有专门的显示数据的控件和存储数据的模型,可以显示和存储不同形式的数据。显示数据的控件分为两类,一类是基于项(item)的控件,另一类是基于模型(model)的控件,基于项的控件是基于模型的控件的简便类。基于项的控件把读取到的数据存储到项中,基于模型的控件......
  • 一个非常实用的Win系统瘦身项目,轻量好用,能去除预装应用程序,还能禁用那些偷偷摸摸收集
    Win经常我们都经常用,但系统里总是预装了一些我们可能并不需要的应用程序。这些应用不仅占用了宝贵的存储空间,还可能拖慢了我们的电脑速度。特别是Windows11,一些花里胡哨的功能和后台服务,让我们的电脑变得不那么“清爽”。今天给大家介绍一个非常实用的Win系统瘦身项目-Win11......
  • 【JAVA 基础 第(16)课】自定义异常类,会更帅哦
    自定义异常类   编译期异常类: class异常类名 extendsException{}   运行期异常: class异常类名extendsRuntimeException{}   类中添加两个构造方法:一个默认消息的构造方法,一个是指定消息的构造方法代码示例:自定义一个游戏输赢异常类publicclassNot_......
  • C语言常用数据类型和自定义数据类型的存储空间
    C语言常用数据类型和自定义数据类型的存储空间想知道各种数据类型的存储空间长度,编码测试,代码如下:注意:用到offsetof宏,在stddef.h头文件中定义,一定要包含进去!!!/*filename:sizeof.c*/#include<stdio.h>#include<stddef.h>//foroffsetofmacro/*compile:gccsizeof......
  • IDEA自定义注解配置
    一、类注释1、打开设置打开设置:Settings->Editor->FileandCodeTemplates,如下图。FileHeader.java为引用的模板文件类头文件注释模板(FileHeader.java)/***@title${NAME}*@date${DATE}${TIME}*@authoryou-ni*@descriptionTODO*/二、方法注释1、打......
  • 如何实现一个自定义表单?
    实现一个自定义表单主要涉及HTML、CSS和JavaScript的使用。以下是一个简单的步骤指南,帮助你从头开始创建一个自定义表单:HTML结构:使用<form>标签来创建表单。在<form>内部,使用各种输入元素,如<input>、<textarea>、<select>等,来创建不同类型的表单字段。为每个输入元素设置na......