WinForm GDI 通过绘制背景图和定时器实现按钮冷却动画效果
序:
这也是我第一次接触Winform GDI,也是正是有了这个需求才让我了解到GDI画图,本来第一次尝试想用OnPaint和OnBackgroundPaint事件去实现这个效果,但是琢磨了好久还是没办法去实现这个效果,于是乎再次面向百度编程,山重水复疑无路,柳暗花明又一村(此处省略过程。。。。。。。。。),不经意间发现了一个GDI绘制背景图的文章,突然便有了下文!
一、浅了解一下GDI
GDI(Graphics Device Interface,图形设备接口),主要负责Windows系统与绘图程序之间的信息交换,处理所有Windows程序的图形输出。
GDI的常用对象有Graphics、Pen、Font、Brush等。
在GDI的所有类中,Graphics类是核心,在绘制任何图形之前,一定要先创建或得到一个Graphics类的对象。
那么什么是Graphics呢?(我觉得类似于个画布)
可以将Graphics对象理解成一个画图环境,这个画图环境包括:要画在什么东西上,用什么画(什么颜色,类型的画笔,画刷),怎么画(画圆形还是方形等等)。
二、代码实现及效果
为了方便使用,我继承了Button按钮控件,封装了一个类,需求里还包含设置冷却时间和设置按钮冷却时的颜色。MyButton代码如下:
/// <summary>
/// 扩展按钮类
/// </summary>
public partial class MyButton : Button
{
/// <summary>
/// 冷却动画定时器
/// </summary>
private readonly Timer cdTimer = new Timer();
/// <summary>
/// 冷却动画每帧恢复宽度
/// </summary>
private float intertvalWidthAdd;
/// <summary>
/// 冷却动画已恢复可用背景色的宽度
/// </summary>
private float enableWidth;
/// <summary>
/// 点击间隔的毫秒数
/// </summary>
[Browsable(true)]
[Category("自定义"), Description("点击间隔的毫秒数"), DisplayName("ClickInterval"), DefaultValue("0")]
public uint ClickInterval
{
get;
set;
}
/// <summary>
/// 禁用状态的背景色
/// </summary>
[Browsable(true)]
[Category("自定义"), Description("禁用时的背景色"), DisplayName("DisBackColor"), DefaultValue(typeof(Color), "Gray")]
public Color DisBackColor { get; set; } = Color.Gray;
/// <summary>
/// 原始背景色
/// </summary>
private Color _backColor;
/// <summary>
/// 按钮初始化
/// </summary>
public DnkButton() : base()
{
//定时间间隔时间
cdTimer.Interval = 100;
cdTimer.Tick += Awaiting_Paint;
Click += DnkButton_Click;
}
/// <summary>
/// 按钮点击处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void DnkButton_Click(object sender, EventArgs e)
{
if (ClickInterval != 0)
{
//禁用按钮
Enabled = false;
//获取原始背景色
_backColor = BackColor;
//按钮禁用,显示用户设置的禁用颜色
BackColor = DisBackColor;
//重新计算冷却动画每帧变化宽度
intertvalWidthAdd = Width / (float)(ClickInterval / cdTimer.Interval);
cdTimer.Start();
}
}
/// <summary>
/// 按钮冷却时的处理(冷却动画)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Awaiting_Paint(object sender, EventArgs e)
{
//按钮已恢复可用背景色的宽度
enableWidth += intertvalWidthAdd;
if (enableWidth < Width)
{
//绘制一张两种颜色组合的矩形作为背景图实现动画效果
Bitmap newGradientBackImg = new Bitmap(Width, Height);
//定义刷子颜色
Brush brush = new SolidBrush(_backColor);
Brush disbrush = new SolidBrush(DisBackColor);
//在图newGradientBackImg上创建一个Graphics类型的可编辑图层
Graphics gr = Graphics.FromImage(newGradientBackImg);
//绘制两个不同大小、不同颜色的矩形(双拼 好理解)
gr.FillRectangle(brush, new RectangleF(0, 0, enableWidth, Height));
gr.FillRectangle(disbrush, new RectangleF(enableWidth, 0, Width - enableWidth, Height));
//设置为背景图
BackgroundImage = newGradientBackImg;
}
else
{
cdTimer.Stop();
Enabled = true;
BackColor = _backColor;
BackgroundImage = null;
//重置
enableWidth = 0;
}
}
}