2016-08-18 53 views
1

我想在按下按钮时将动画应用到我的按钮。在WPF中,我可以使用带触发器的Storyboard来创建动画。这里有一个例子:按钮的动画发光效果 - C#Windows窗体

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

的WinForms是不是真的很好。 – Maarten

+0

对于无用的浮华做留在WPF .. – TaW

+0

是啊,WPF是好的。但问题是我没有一台好的电脑。我可能会问一个关于任务和性能的新问题。@ TaW @Maarten – Jandy

回答

3

主要想法是使用计时器和alphablending发光颜色与原始背景颜色。

例如,您可以将按钮的FlatStyle设置为Flat并覆盖OnMouseEnterOnMouseLeave。在OnMouseEnter启动定时器,并在和OnMouseLeave停止计时器。在计时器Tick事件中,您可以将按钮的FlatAppearanceMouseOverBackColor设置为您在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); 
    } 
} 
+0

我现在使用wpf.but哇的想法。我需要注意这一点。+ 2如果我可以@ Reza Aghaei – Jandy

+0

感谢您的反馈:)是的,这很好,也可以应用这种技术,而不需要将样式设置为平面,通过关闭视觉样式背景颜色并更改'BackColor '用定时器。 –

1

你会得到的WinForms最近可能是使它DoubleBuffered。 WinForms对动画不太好。

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

SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 

否则,请在属性DoubleBuffered的形式,或通过代码:

DoubleBuffered = true; 

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

+0

DoubleBuffered = true;在形式和延迟时间是好的1.2似乎是好的。但仍然快。@ PaddiM8 – Jandy