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

时间:2016-08-18 14:02:22

标签: c# winforms button custom-controls

我想在按下按钮时将动画应用到我的按钮。在WPF中,我可以使用带有触发器的Storyboard来创建动画。这是一个例子:

<Storyboard x:Key="AniOpacityDelay">
  <DoubleAnimation
    Storyboard.TargetName="background"
    Storyboard.TargetProperty="Opacity"
    AutoReverse="True"
    To="0.65"
    Duration="0:0:0.2"/>
</Storyboard>

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

  <EasingColorKeyFrame KeyTime="0" Value="#EEEEEE"/>
</ColorAnimationUsingKeyFrames>

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);
}

2 个答案:

答案 0 :(得分:5)

主要思想是使用计时器并将发光颜色与原始背景颜色混合。

例如,您可以将按钮的FlatStyle设置为Flat并覆盖OnMouseEnterOnMouseLeave。在OnMouseEnter启动计时器并进入,OnMouseLeave停止计时器。在计时器Tick活动中,您可以将MouseOverBackColor按钮的FlatAppearance设置为您在Tick事件中增加其Alpha通道的颜色。

Glow Button

发光按钮代码

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);
    }
}

答案 1 :(得分:1)

你最接近winforms的可能是DoubleBuffered。 WinForms对动画效果不佳。

如果您使用的是自定义控件,请在Initialize();

下添加
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

否则,在属性中生成DoubleBuffered形式,或者通过代码:

DoubleBuffered = true;

然后创建动画(如果你还没有想到这一点),做一个循环检查动画是否完成(在计时器事件中)。