问题
I want to apply animation to my button when pressing button. In WPF I can use Storyboard
with triggers to create animation. Here is an example:
<Storyboard x:Key="AniOpacityDelay">
<DoubleAnimation
Storyboard.TargetName="background"
Storyboard.TargetProperty="Opacity"
AutoReverse="True"
To="0.65"
Duration="0:0:0.2"/>
</Storyboard>
and:
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="Itemcont"
Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="#EEEEEE"/>
</ColorAnimationUsingKeyFrames>
Windows Forms doesn't have Storyboard
and triggers. How to make smooth animation in Windows Forms?
Here's my code for Windows Forms:
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);
}
回答1:
The basic idea is using a Timer and alpha-blending the glow color with original background color.
For example you can set FlatStyle of the button to Flat
and override OnMouseEnter and OnMouseLeave. In OnMouseEnter
start the timer and in and OnMouseLeave
stop the timer. In timer Tick
event you can set the MouseOverBackColor of FlatAppearance of button to a color which you increase it's alpha channel in Tick event.

Glow Button Code
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);
}
}
回答2:
The nearest you will get with winforms is probably making it DoubleBuffered. WinForms isn't very good for animations.
If you're using a custom control, add this under Initialize();
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
Otherwise, make the form DoubleBuffered in the properties, or by code:
DoubleBuffered = true;
Then to create the animation(if you haven't already figured that out), do a loop checking if the animation is completed(in the timer event).
来源:https://stackoverflow.com/questions/39020262/animated-glow-effect-for-button-c-sharp-windows-forms