2012-04-16 86 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; 
}