zoukankan      html  css  js  c++  java
  • [C#] (原创)一步一步教你自定义控件——03,SwitchButton(开关按钮)

    一、前言

    技术没有先进与落后,只有合适与不合适。

    本篇的自定义控件是:开关按钮(SwitchButton)。

    开关按钮非常简单,实现方式也多种多样,比如常见的:使用两张不同的按钮图片,代表开和关,然后在点击时切换这两张图片。

    而本篇和前两篇一脉相承,都是继承Control,使用GDI+去实现。因为都是相同的原理,所以如果看过前两篇的讲解,自己就可以实现出来。

    虽说简单,但仍有可雕琢之处,在基本的实现外,我还会加入缓动效果,以达到更加自然的动画效果。

    关于缓动,可以查看这两篇文章:

    《三角函数与缓入缓出动画及C#实现(图文讲解)》

    《缓动公式整理(附:C#实现及WPF原版对比)》

    相信看完的你,一定会有所收获。

    本文地址:https://www.cnblogs.com/lesliexin/p/13552662.html


    二、前期分析

    (一)为什么需要开关按钮?

    “开关按钮(SwitchButton)”虽然不常听说,但是到处都可以见到它的身影,手机、电脑、网页等等到处都有“开关按钮”。

    “开关按钮”的基本样式如下:

    “开关按钮”效果很直观,使用也很方便,但是在WinForm中却没有提供该控件,所以便需要自己去实现“开关按钮”。

    (二)实现目标

    1,外观

    基本外观如下:

    同时可以配合Label控件来进行提示:

    2,功能和特点

    (1)支持动画效果

    不是简单的“开”、“关”两个状态生硬的切换,而是需要有相应的动画效果,包括按钮圆点位置的变化、颜色的变化。

    同时为了使圆点的移动更加自然,需要使用缓动效果。

    (2)支持修改颜色

    可以修改“关”时的背景条颜色、“开”时的背景条颜色、按钮圆点的颜色。

    (3)支持修改按钮圆点的大小和背景条的大小

    比如将按钮圆点调小一点,便可以实现类似Win10中开关按钮的效果:

    比如将背景条调细,便可以实现很特别的效果:

    (三)技术分析

    仍是使用GDI+去实现,其原理上就是在简化版的LTrackBar上加一个圆点。

    而动画效果,就是改变圆点的位置和前景条的宽度。关于动画效果的的实现原理可以参考《三角函数与缓入缓出动画及C#实现(图文讲解)》


    三、开始实现

    (一)前期准备。

    此处仅作提纲,具体操作见前篇。

    新建类:LSwitchButton.cs

    添加继承:Control(需要添加引用:System.Windows.Forms.dll)

    修改可访问性为:public

    (二)添加属性

    1,”开“状态时背景条颜色

    此颜色是当开关按钮代表”开“的时候背景条的颜色。

    2,”关“状态时背景条颜色

    此颜色是当开关按钮代表”关“的时候背景条的颜色。

    3,按钮圆点颜色

    此颜色是按钮圆点的颜色

    4,背景条高度

    背景条的高度即可以高于按钮圆点,也可以低于按钮圆点。

    5,按钮圆点高度

    按钮圆点高度(直径)即可以高于背景条高度,也可以低于背景条高度。

    因为“背景条高度”和“按钮圆点高度”不一定谁高谁低,所以为了方便使用,将自动调整控件尺寸为两者较高的一方。

    6,圆点距左右两侧距离

    当“背景条高度”大于“按钮圆点高度”时,为了使按钮圆点边缘距背景条边缘距离相等,所以需要通过此属于去设置。

    比如:背景条高度为24,圆点高度为20,那么将本属性设置为(24-20)/2=2,即可达到圆点边缘距背景条边缘距离相等。

    7,”开“、”关“状态

    此状态用于标识或设置开关按钮的开关状态。

    (三)添加事件

    对于开关按钮而言,只需要一个事件,那就是开关状态发生改变时所产生的事件。

    其中事件数据如下:

    (四)重写方法

    1,OnPaint

    在本方法中,我们要画三个:背景条、前景条、圆点。

    2,OnMouseDown

    本方法代表鼠标点击了开关按钮。在此方法中,我们要实现以下操作:改变开关状态、启动动画效果。

    而动画效果的实现,是使用定时器,不断改变位置,并发生重绘。

    在动画效果结束后,停止定时器,并触发开关状态改变事件:LSwitched。之所以在此处触发事件而不是在OnMouseDown中触发,是为了避免事件LSwitched的实现阻塞动画效果的实现。

    在定时器事件中,使用了《缓动公式整理(附:C#实现及WPF原版对比)》中所编译的DLL,其调用的方法源代码如下,不想引用该DLL可以直接使用下方代码代替。

    (五)添加双缓冲

    为了避免重绘时闪烁,可在其构造函数中加上对双缓冲的支持。

    (六)添加默认事件

    为了实现双击控件就自动实现仅有的一个事件,故添加默认事件。


    四、效果演示

    在Form上添加本控件:LSwitchButton,调整控件各个属性,并在旁边添加一Label。

    双击本控件,在事件中输入以下代码:

    运行程序,即可见到以下效果:


    五、调整优化

    就像本文开篇所说那样:虽然简单,但仍可雕琢。在这里,将会对开关控件进行调整和优化。

    (一)圆点切边优化

    虽然乍看起来没什么问题,但是在某些情况下,会发现按钮圆点下方会被切去一点。如下:

    虽然实现逻辑上是没有问题的,但是实际效果确有此偏差,所以在这里我们需要手动去调整,将控件的高度多添加一个像素,这样就可以解决切边问题了。

    (二)多种缓动效果支持

    即然在本例中已经引用了缓动DLL(见:《缓动公式整理(附:C#实现及WPF原版对比)》),那么不妨使开关按钮的动画支持所有缓动效果。

    1,添加缓动效果属性

    2,修改定时器事件,添加所有缓动效果支持

    3,不同缓动效果开关按钮演示

    注:由于GIF录制帧率的限制,下方的缓动演示效果比实际效果要差上很多。

    (1),默认(Quartic)

    (2),Back

    (3),Bounce


    六、结束语

    本篇并没有什么复杂难懂的知识,更多的是对已掌握知识的运用,特别是对前篇《缓动公式整理(附:C#实现及WPF原版对比)》中的缓动效果的使用。

    技术并没有先进和落后,只有合适与不合适。

    所以,对自己掌握的知识多抱有一些信心,尽情释放自己的想像力,并在实践中提升自己。


    七、源代码及工程下载

    https://files.cnblogs.com/files/lesliexin/03,LSwitchButton.7z

  • 相关阅读:
    最大流模板
    大数相加
    . Number throry
    掷骰子 dp
    Java常用类库2
    简单注册功能(未连接数据库)
    Java常用类库
    人机猜拳
    租车系统
    Java一些概念
  • 原文地址:https://www.cnblogs.com/lesliexin/p/13552662.html
Copyright © 2011-2022 走看看