2012-04-16 83 views
6

我有一个可以显示或隐藏的详细信息面板。淡出面板 - Windows窗体

如何为显示/隐藏该面板(当然还有其内容)做出简单的淡入淡出效果?

我正在使用Windows窗体,并且控件在Windows窗体中没有opacity属性。

+1

你知道的。 'panel'没有任何'opacity'属性。这是不可能的。你应该使用'WPF'来做到这一点! – 2012-04-16 17:16:26

+0

@SteveWong问题已更新。 – 2012-04-16 17:18:16

+2

应该使用WPF来代替 – 2012-04-16 17:19:34

回答

17

这在Winforms中是相当可行的,它只能以看上去就像淡入淡出。一种技术是使用Control.DrawToBitmap()来创建控件的位图。然后用定时器从背景位图混合到前景位图。

我将使用UserControl而不是Panel,因此您可以使用Winforms设计器来设计控件。该代码将在任何类型的控制下工作。为您的项目添加一个新类并粘贴下面显示的代码。编译。使用Project +添加新项目,Windows窗体节点,“继承的用户控件”模板并从弹出列表中选择FadeControl,从此创建您自己的UserControl。正常设计用户控制。

如书面所示,只要将控件添加到父级,控件就会自动从父级的BackColor淡出到控件内容。调用FadeOut()使其融合回到背景。如果您想在控制完成时自动处理该控件,则通过true。您可以使用FadeIn()和Faded属性来手动控制淡入淡出。您可以调整注释为//可调整的行中的数字以调整动画。如果父母具有不透明的背景,则需要额外的工作。

using System; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Windows.Forms; 

class FadeControl : UserControl { 

    public FadeControl() { 
     pbox = new PictureBox(); 
     pbox.BorderStyle = BorderStyle.None; 
     pbox.Paint += new PaintEventHandler(pbox_Paint); 
     fadeTimer = new Timer(); 
     fadeTimer.Interval = 15; // tweakable 
     fadeTimer.Tick += new EventHandler(fadeTimer_Tick); 
    } 

    public bool Faded { 
     get { return blend < 0.5f; } 
    } 
    public void FadeIn() { 
     stopFade(false); 
     createBitmaps(); 
     startFade(1); 
    } 
    public void FadeOut(bool disposeWhenDone) { 
     stopFade(false); 
     createBitmaps(); 
     disposeOnComplete = disposeWhenDone; 
     startFade(-1); 
    } 

    private void createBitmaps() { 
     bmpBack = new Bitmap(this.ClientSize.Width, this.ClientSize.Height); 
     using (var gr = Graphics.FromImage(bmpBack)) gr.Clear(this.Parent.BackColor); 
     bmpFore = new Bitmap(bmpBack.Width, bmpBack.Height); 
     this.DrawToBitmap(bmpFore, this.ClientRectangle); 
    } 
    void fadeTimer_Tick(object sender, EventArgs e) { 
     blend += blendDir * 0.02F; // tweakable 
     bool done = false; 
     if (blend < 0) { done = true; blend = 0; } 
     if (blend > 1) { done = true; blend = 1; } 
     if (done) stopFade(true); 
     else pbox.Invalidate(); 
    } 
    void pbox_Paint(object sender, PaintEventArgs e) { 
     Rectangle rc = new Rectangle(0, 0, pbox.Width, pbox.Height); 
     ColorMatrix cm = new ColorMatrix(); 
     ImageAttributes ia = new ImageAttributes(); 
     cm.Matrix33 = blend; 
     ia.SetColorMatrix(cm); 
     e.Graphics.DrawImage(bmpFore, rc, 0, 0, bmpFore.Width, bmpFore.Height, GraphicsUnit.Pixel, ia); 
     cm.Matrix33 = 1F - blend; 
     ia.SetColorMatrix(cm); 
     e.Graphics.DrawImage(bmpBack, rc, 0, 0, bmpBack.Width, bmpBack.Height, GraphicsUnit.Pixel, ia); 
    } 

    private void stopFade(bool complete) { 
     fadeTimer.Enabled = false; 
     if (complete) { 
      if (!Faded) this.Controls.Remove(pbox); 
      else if (disposeOnComplete) this.Dispose(); 
     } 
     if (bmpBack != null) { bmpBack.Dispose(); bmpBack = null; } 
     if (bmpFore != null) { bmpFore.Dispose(); bmpFore = null; } 
    } 
    private void startFade(int dir) { 
     this.Controls.Add(pbox); 
     this.Controls.SetChildIndex(pbox, 0); 
     blendDir = dir; 
     fadeTimer.Enabled = true; 
     fadeTimer_Tick(this, EventArgs.Empty); 
    } 

    protected override void OnCreateControl() { 
     base.OnCreateControl(); 
     if (!DesignMode) FadeIn(); 
    } 
    protected override void OnResize(EventArgs eventargs) { 
     pbox.Size = this.ClientSize; 
     base.OnResize(eventargs); 
    } 
    protected override void Dispose(bool disposing) { 
     if (disposing) { 
      stopFade(false); 
      pbox.Dispose(); 
      fadeTimer.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 

    private PictureBox pbox; 
    private Timer fadeTimer; 
    private Bitmap bmpBack, bmpFore; 
    private float blend; 
    private int blendDir = 1; 
    private bool disposeOnComplete; 
}