直接看效果图了,不想拷贝代码了
源码下载
下载的源码里面是没有动画切换效果的,下面贴出的代码是修改后带动画效果的源码,两个类:ToggleButtonStyle.cs和ToggleButton.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 ToggleButtonTest.ToggleButton.TypeConverters;
using System.Drawing.Drawing2D;
using ToggleButtonTest.ToggleButton.Common;
namespace ToggleButtonTest.ToggleButton
{
[ToolboxItem(true)]
[ToolboxBitmap(typeof(CheckBox))]
public partial class ToggleButton : Control
{
private ToggleButtonStyle _ToggleButtonStyle;
private Rectangle _MouseRect;
private bool _Checked;
private Color _StateColor;
private bool _DotFocus;
private bool _DotClick;
private bool _EnabledToggle = true;
//动画效果移动距离
private int _EffectDistance=0;
//DOT是否移动
private bool _IsMoving = false;
///
/// ToggleButton状态改变
/// 返回true,ToggleButton状态改变,否则状态回滚
///
///
public delegate bool DelToggleStateChanged(bool isChecked);
[Browsable(true), Description("ToggleButton状态改变")]
public event DelToggleStateChanged OnToggleStateChanged;
public ToggleButton()
{
InitializeComponent();
this.Size = new Size(70, 35);
_ToggleButtonStyle = new ToggleButtonStyle(this);
//SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw |
ControlStyles.SupportsTransparentBackColor |
ControlStyles.UserMouse |
ControlStyles.Selectable |
ControlStyles.StandardClick, true);
}
[Browsable(true), Description("ToggleButton样式设置"), Category("ToggleButton")]
[Localizable(true)]
[MergableProperty(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ToggleButtonStyle ButtonStyle
{
get
{
return _ToggleButtonStyle;
}
set
{
_ToggleButtonStyle = value;
}
}
///
/// 设置ToggleButton可操作性,相当于Enabled
///
[Browsable(true), Description("设置ToggleButton可操作性")]
public bool EnabledToggle
{
get
{
return _EnabledToggle;
}
set
{
if (_EnabledToggle != value)
{
_EnabledToggle = value;
_DotClick = false;
_DotFocus = false;
this.Invalidate();
}
}
}
///
/// 请使用EnableToogle
///
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new bool Enabled { get { return false; } set { } }
///
/// ToggleButton是否选中
///
[Browsable(true), Description("ToggleButton是否选中")]
public bool Checked
{
get
{
return _Checked;
}
set
{
//如果value值未改变,则放弃执行,减少UI渲染,避免不必要的刷新Invalidate()
if (_Checked == value)
{
return;
}
if (_IsMoving)
{
return;
}
_DotClick = false;
_DotFocus = false;
_Checked = value;
if (ButtonStyle.AnimateEnable)
{
_EffectDistance = !value ? FixedMoveEndDistance : FixedMoveStartPosition;
PlayAnimate();
}
else
{
this.Invalidate();
}
}
}
private Timer timer;
private void PlayAnimate()
{
_IsMoving = true;
if (timer != null)
{
timer.Enabled = false;
timer = null;
}
timer = new Timer();
timer.Tick += Animate_Effect;
timer.Interval = 30;//30ms执行一次;
timer.Enabled = true;
}
private void Animate_Effect(object sender, EventArgs e)
{
//每次移动5px;
//取消选中
var endAnimate = false;
if (!_Checked)
{
_EffectDistance -=ButtonStyle.AnimateDisp;
if (_EffectDistance <= FixedMoveStartPosition)
{
_EffectDistance = FixedMoveStartPosition;
endAnimate = true;
}
}
else
{
_EffectDistance += ButtonStyle.AnimateDisp;
if (_EffectDistance >= FixedMoveEndDistance)
{
_EffectDistance = FixedMoveEndDistance;
endAnimate = true;
}
}
if (endAnimate)
{
_IsMoving = false;
if (timer != null)
{
timer.Enabled = false;
timer = null;
}
}
//刷新视图
this.Invalidate();
}
private int MovingX
{
get
{
if (_IsMoving)
{
return _EffectDistance;
}
else
{
return _Checked ? FixedMoveEndDistance : FixedMoveStartPosition;
}
}
}
protected override void OnMouseClick(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (_MouseRect != null && _MouseRect.Contains(new Point(e.X, e.Y)) && this.EnabledToggle)
{
Checked = !Checked;
if (OnToggleStateChanged != null)
{
var suc = OnToggleStateChanged(Checked);
if (!suc)
{
Checked = !Checked;
}
}
}
}
base.OnMouseClick(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
var dotFocus = EnabledToggle && _MouseRect != null && _MouseRect.Contains(new Point(e.X, e.Y));
if (_DotFocus != dotFocus)
{
_DotFocus = dotFocus;
this.Invalidate();
}
base.OnMouseMove(e);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_DotClick = EnabledToggle && _MouseRect != null && _MouseRect.Contains(new Point(e.X, e.Y));
if (_DotClick)
{
this.Invalidate();
}
}
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (_DotClick)
{
_DotClick = false;
this.Invalidate();
}
base.OnMouseDown(e);
}
///
/// 圆圈固定移动终止距离
///
private int FixedMoveEndDistance
{
get
{
//DOT大小
var dotDis = this.ClientRectangle.Width > this.ClientRectangle.Height ? this.Height : this.Width;
dotDis = dotDis - 2 * ButtonStyle.DotDistance - 2 * ButtonStyle.BorderWidth;
//会与DOT冲突
var distance= this.ClientRectangle.Width > this.ClientRectangle.Height ? this.Width : this.Height;
distance =distance-dotDis-ButtonStyle.BorderWidth-ButtonStyle.DotDistance;
return distance;
}
}
///
/// 圆圈固定移动起始位置
///
public int FixedMoveStartPosition
{
get
{
return ButtonStyle.BorderWidth + ButtonStyle.DotDistance;
}
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; //使绘图质量最高,即消除锯齿
var dotDis = this.ClientRectangle.Width > this.ClientRectangle.Height ? this.Height : this.Width;
var rect = new Rectangle(0, 0, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);
var bRect = new Rectangle(0, 0, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);
var roundRectR = new RectangleR(rect, dotDis / 2);
var borderRectR = new RectangleR(bRect, dotDis / 2);
//画背景
FillRectangle(e.Graphics, roundRectR, ButtonStyle.ToggleButtonBackColor);
var x = ButtonStyle.DotDistance;
dotDis = dotDis - 2 * x - 2 * ButtonStyle.BorderWidth;
var y = (this.ClientRectangle.Height - dotDis) / 2;
var starX = MovingX;
if (Checked&&!ButtonStyle.AnimateEnable)
{
starX = this.ClientRectangle.Width - dotDis-x-ButtonStyle.BorderWidth;
}
//Dot区域
_MouseRect = new Rectangle(starX, y, dotDis, dotDis);
_StateColor = ButtonStyle.ToggleOffColor;
if (Checked)
{
_StateColor = ButtonStyle.ToggleOnColor;
}
if (EnabledToggle == false)
{
_StateColor = ColorTranslator.FromHtml("#c0bfbf");
}
//画边框
DrawPathBorder(e.Graphics, borderRectR, _StateColor, ButtonStyle.BorderWidth);
//处理dot
if (_DotFocus&&!_IsMoving)
{
_StateColor = ButtonStyle.ToggleOffFocusColor;
if (Checked)
{
_StateColor = ButtonStyle.ToggleOnFocusColor;
}
}
if (_DotClick&&!_IsMoving)
{
var offColor = ButtonStyle.ToggleOffColor;
var offX = -2;
if (Checked)
{
offX = 2;
offColor = ButtonStyle.ToggleOnColor;
}
//画阴影
var offRect = _MouseRect;
offRect.Offset(offX, 0);
using (var brush = new SolidBrush(offColor))
{
e.Graphics.FillEllipse(brush, offRect);
}
}
//画圆DOT
using (var brush = new SolidBrush(_StateColor))
{
e.Graphics.FillEllipse(brush, _MouseRect);
}
e.Graphics.ResetClip();
}
private void FillRectangle(Graphics g, RectangleR roundRect, Color color)
{
if (roundRect.Rect.Width <= 0 || roundRect.Rect.Height <= 0)
{
return;
}
using (GraphicsPath path = roundRect.ToGraphicsBezierPath())
{
using (Brush brush = new SolidBrush(color))
{
g.FillPath(brush, path);
}
}
}
private void DrawPathBorder(Graphics g, RectangleR roundRect, Color color, int borderWidth)
{
using (GraphicsPath path = roundRect.ToGraphicsBezierPath())
{
using (Pen pen = new Pen(color, borderWidth))
{
g.DrawPath(pen, path);
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ToggleButtonTest.ToggleButton.TypeConverters
{
///
/// ToggleButton属性样式设置
///
[TypeConverter(typeof(ExpandableObjectConverter))]
public class ToggleButtonStyle
{
private Control _control;
private Color _ToggleOnColor;
private Color _ToggleOffColor;
private Color _ToggleButtonBackColor;
private int _DotDistance;
private int _BorderWidth;
private Color _ToggleOnFocusColor;
private Color _ToggleOffFocusColor;
private bool _AnimateEnable = true;
//使用动画时的位移量
private int _AnimateDisp= 10;
public ToggleButtonStyle(Control control)
{
this._control = control;
this._ToggleOnColor = ColorTranslator.FromHtml("#0099ff");
this._ToggleOffColor = Color.Gray;
this._ToggleButtonBackColor = Color.White;
this._DotDistance = 4;
this._BorderWidth = 1;
this._ToggleOnFocusColor = ColorTranslator.FromHtml("#96d7ff");
this._ToggleOffFocusColor = ColorTranslator.FromHtml("#c0bfbf");
}
///
/// ToggleButton开启动画效果时的偏移量,最小值10px
///
[Browsable(true), Description("ToggleButton开启动画效果时的偏移量,最小值10px")]
public int AnimateDisp
{
get
{
return _AnimateDisp;
}
set
{
if (value < 10)
{
value = 10;
}
_AnimateDisp = value;
}
}
///
/// ToggleButton状态切换时是否开启动画效果
///
[Browsable(true), Description("ToggleButton状态切换时是否开启动画效果")]
public bool AnimateEnable
{
get
{
return _AnimateEnable;
}
set
{
_AnimateEnable = value;
}
}
///
/// ToggleButton打开时颜色
///
[Browsable(true), Description("ToggleButton打开时颜色")]
public Color ToggleOnColor
{
get
{
return _ToggleOnColor;
}
set
{
_ToggleOnColor = value;
_control.Invalidate();
}
}
///
/// ToggleButton打开时获取焦点颜色
///
[Browsable(true), Description("ToggleButton打开时获取焦点颜色")]
public Color ToggleOnFocusColor
{
get
{
return _ToggleOnFocusColor;
}
set
{
_ToggleOnFocusColor = value;
_control.Invalidate();
}
}
///
/// ToggleButton关闭时颜色
///
[Browsable(true), Description("ToggleButton关闭时颜色")]
public Color ToggleOffColor
{
get
{
return _ToggleOffColor;
}
set
{
_ToggleOffColor = value;
_control.Invalidate();
}
}
///
/// ToggleButton关闭时获取焦点颜色
///
[Browsable(true), Description("ToggleButton关闭时获取焦点颜色")]
public Color ToggleOffFocusColor
{
get
{
return _ToggleOffFocusColor;
}
set
{
_ToggleOffFocusColor = value;
_control.Invalidate();
}
}
///
/// ToggleButton背景色,非BackColor
///
[Browsable(true), Description("ToggleButton背景色,非BackColor")]
public Color ToggleButtonBackColor
{
get
{
return _ToggleButtonBackColor;
}
set
{
_ToggleButtonBackColor = value;
_control.Invalidate();
}
}
///
/// 圆点到边界的距离
///
[Browsable(true), Description("圆点到边界的距离")]
public int DotDistance
{
get
{
return _DotDistance;
}
set
{
if (value <= 0)
{
value = 4;
}
_DotDistance = value; _control.Invalidate();
}
}
///
/// 边框大小
///
[Browsable(true), Description("边框大小")]
public int BorderWidth
{
get
{
return _BorderWidth;
}
set
{
if (value <= 0)
{
value = 1;
}
_BorderWidth = value; _control.Invalidate();
}
}
}
}