按钮的动画发光效果-C#Windows窗体

Jan*_*ndy 2 c# button custom-controls winforms

我想在按下按钮时对按钮应用动画。在WPF中,我可以Storyboard与触发器配合使用来创建动画。这是一个例子:

<Storyboard x:Key="AniOpacityDelay">
  <DoubleAnimation
    Storyboard.TargetName="background"
    Storyboard.TargetProperty="Opacity"
    AutoReverse="True"
    To="0.65"
    Duration="0:0:0.2"/>
</Storyboard>
Run Code Online (Sandbox Code Playgroud)

和:

<ColorAnimationUsingKeyFrames
  Storyboard.TargetName="Itemcont"
  Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">

  <EasingColorKeyFrame KeyTime="0" Value="#EEEEEE"/>
</ColorAnimationUsingKeyFrames>
Run Code Online (Sandbox Code Playgroud)

Windows窗体没有Storyboard和触发器。如何在Windows窗体中制作平滑的动画?

这是我的Windows窗体代码:

void DelayTime()
{
  timer = new Timer();
  timer.Interval = (int)System.TimeSpan.FromSeconds(this.DelayTime).TotalMilliseconds;
  timer.Tick += (s, es) =>
  {
    this.mouseover = false; 
    this.Cursor = Cursors.Hand;
    this.Enabled = true;
  };
  timer.Start();
}

protected override void OnMouseDown(MouseEventArgs mevent)
{
  base.OnMouseDown(mevent);
  mouseover = true;
  this.Enabled = false;
  DelayTime();
}

protected override void OnPaint(PaintEventArgs e)
{
  Color bg = this._Background;
  bg = mouseover ? this._HoverColor : this._Background;
  e.Graphics.FillRectangle(new SolidBrush(bg), this.ClientRectangle);
}
Run Code Online (Sandbox Code Playgroud)

Rez*_*aei 5

基本思想是使用a Timer和alpha混合发光颜色和原始背景颜色。

例如,您可以将FlatStyle按钮设置为,Flat并覆盖OnMouseEnterOnMouseLeave。在OnMouseEnter启动计时器,在启动和OnMouseLeave停止计时器。在计时器Tick事件中,您可以将MouseOverBackColorof FlatAppearance的按钮设置为一种颜色,以便在Tick事件中增加其alpha通道。

发光按钮

发光按钮代码

using System;
using System.Drawing;
using System.Windows.Forms;
public class GlowButton : Button
{
    Timer timer;
    int alpha = 0;
    public Color GlowColor { get; set; }
    public GlowButton()
    {
        this.DoubleBuffered = true;
        timer = new Timer() { Interval = 50 };
        timer.Tick += timer_Tick;
        this.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
        this.GlowColor = Color.Gold;
        this.FlatAppearance.MouseDownBackColor = Color.Gold;
    }
    protected override void OnMouseEnter(EventArgs e)
    {
        base.OnMouseEnter(e);
        this.FlatAppearance.MouseOverBackColor = CalculateColor();
        timer.Start();
    }
    protected override void OnMouseLeave(EventArgs e)
    {
        base.OnMouseLeave(e);
        timer.Stop();
        alpha = 0;
        this.FlatAppearance.MouseOverBackColor = CalculateColor();
    }
    void timer_Tick(object sender, EventArgs e)
    {
        int increament = 25;
        if (alpha + increament < 255) { alpha += increament; }
        else { timer.Stop(); alpha = 255; }
        this.FlatAppearance.MouseOverBackColor = CalculateColor();
    }
    protected override void Dispose(bool disposing)
    {
        if (disposing) timer.Dispose();
        base.Dispose(disposing);
    }
    private Color CalculateColor()
    {
        return AlphaBlend(Color.FromArgb(alpha, GlowColor), this.BackColor);
    }
    public Color AlphaBlend(Color A, Color B)
    {
        var r = (A.R * A.A / 255) + (B.R * B.A * (255 - A.A) / (255 * 255));
        var g = (A.G * A.A / 255) + (B.G * B.A * (255 - A.A) / (255 * 255));
        var b = (A.B * A.A / 255) + (B.B * B.A * (255 - A.A) / (255 * 255));
        var a = A.A + (B.A * (255 - A.A) / 255);
        return Color.FromArgb(a, r, g, b);
    }
}
Run Code Online (Sandbox Code Playgroud)