2011-05-24 180 views
7

WinForm的控制I有一個具有在其自身上某些控件(btnCreateReport,pnlDarkLayer).I具有適合於形成面板(基座=填充)形式,它是在所有controls.when使用者的背部點擊的btnCreateReport按鈕,我請pnlDarkLayer BringToFront方法和一些計算之後我請SendToBack()的button.I的方法希望藉助表單控件的黑色層和禁用所有的控制形式。 這可能嗎?謝謝。與不透明度

也許這個代碼幫助ü理解我的目的:

private void btnCreateReport_Click(object sender, EventArgs e) 
{ 
    pnlDarkLayer.BackColor = Color.FromArgb(100, Color.Gray);   

    pnlDarkLayer.BringToFront(); 
    btnCreateReport.Enabled = false; 

    Thread ProcessReport = new Thread(new ThreadStart(ProcessingReport)); 
    ProcessReport.Start(); 
    while (ProcessReport.IsAlive) 
    { 
     Application.DoEvents(); 
    } 
    pnlDarkLayer.SendToBack(); 

    btnCreateReport.Enabled = true; 

} 

此代碼隱藏所有的控制,但我不希望隱藏在form.I控制要對他們繪製的黑色層。用戶必須能看到控件。 我需要像控件的窗體的不透明屬性。

我有測試此:

pnlDarkLayer.CreateGraphics().CompositingMode=System.Drawing.Drawing2D.CompositingMode.SourceOver;

更新:我有測試這一項:(使用的一種形式,而不是板)

private void btnCreateReport_Click(object sender, EventArgs e) 
{   

    btnCreateReport.Enabled = false; 

    frmProgress ProgressForm = new frmProgress(); 
    ProgressForm.TopLevel = false; 
    ProgressForm.Parent = this; 
    ProgressForm.BringToFront(); 
    this.Controls.Add(ProgressForm); 
    ProgressForm.Show(); 

    Thread ProcessReport = new Thread(new ThreadStart(ProcessingReport)); 
    ProcessReport.Start(); 

    while (ProcessReport.IsAlive) 
    { 
     Application.DoEvents(); 
    } 
    ProgressForm.Close(); 
    btnCreateReport.Enabled = true; 

} 

但我不能看ProgressForm以我的形式出現。

+3

除了任何與不透明有關的事情,*請*不要使用調用'DoEvents'的那種循環。給ProcessingReport一些鉤子用來在完成時調用一些代碼,或者只是把最後一段代碼放在ProcessingReport方法的末尾,記得使用BeginInvoke來確保它在UI線程。幾乎所有情況下都應該避免使用'Application.DoEvents'。 – 2011-05-24 06:29:31

+0

那麼線程完成工作後,我該怎麼做? – Saleh 2011-05-24 06:31:20

+0

禁用所有控件,你也可以嘗試這樣做:foreach(控件中的控件){item.Enabled = false;} – Reniuz 2011-05-24 06:35:08

回答

6

從Winforms中http://support.microsoft.com/kb/943454

透明控制是 相對透明它們的父, 不其他控件。透明度 的WinForms更像是僞裝 不是真正的透明度。透明 控制實際上並沒有讓你看到 通過 形式背後的控制。它要求其母公司在「透明」控件上繪製自己的背景 。這就是爲什麼一個透明的 控件顯示其背後的窗體,但 涵蓋了其他任何控件。

爲了實現相對於其他 控制透明度的要求做同樣的 的事情,但在更大的規模:只是要求家長對 繪製前臺控制的背景,而不是 , 控制需要詢問所有控件 背後它吸取其背景。 這隻適用於 提供某種方法來請求 它們被繪製,而不會 當 後景控件的圖像更改時自動更新。

該頁面還提供了一個代碼示例(在vb中,悲哀地),以顯示這是如何完成的。

5

如果我理解正確的,你想進行操作時運行「變暗」形式的內容。

某人的前說到這裏,這是非常棘手做對。但有一種方法可以輕鬆完成,只需一次預訂(見下文)。

看這個源代碼:

public partial class Form1 : Form 
{ 
    private Bitmap _background; 
    private bool _isShrouded; 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     if (true == _isShrouded && null!=_background) 
      e.Graphics.DrawImage(_background, 0, 0); 
    } 

    public void Shroud() 
    { 
     if (false == _isShrouded) 
     { 
      CreateScreenshot(); 

      HideControls(); 

      _isShrouded = true; 

      this.Invalidate(); 
     } 
    } 

    public void Unshroud() 
    { 
     if (true == _isShrouded) 
     { 
      ShowControls(); 

      _isShrouded = false; 

      this.Invalidate(); 
     } 


    } 

    private void HideControls() 
    { 
     foreach (Control control in this.Controls) 
      control.Visible = false; 
    } 

    private void ShowControls() 
    { 
     foreach (Control control in this.Controls) 
      control.Visible = true; 
    } 

    private void CreateScreenshot() 
    { 
     Rectangle area = this.RectangleToScreen(this.ClientRectangle); 
     Bitmap screenGrab = new Bitmap(area.Width, area.Height); 

     Brush dark = new SolidBrush(Color.FromArgb(128, Color.Black)); 

     Graphics g = Graphics.FromImage(screenGrab); 
     g.CopyFromScreen(area.Location, Point.Empty, area.Size); 
     g.FillRectangle(dark, 0, 0, area.Width, area.Height); 
     g.Dispose(); 

     _background = screenGrab; 
    } 
} 

Form1類有兩個主要方法,導流罩()和鍼砭()。

Shroud()方法獲取表單的快照,並將其複製到位圖中,然後「變暗」。然後隱藏控件,並將位圖繪製在窗體上。

UnShroud()方法恢復控件,並告訴窗體不再繪製位圖。

它需要兩個私有變量:一個用於存儲位圖,另一個用於維護當前狀態的標誌。

它還會覆蓋OnPaint(),因爲它需要在遮蓋時繪製背景圖像。

注意:屏蔽通過截取表單的方式工作。這意味着表單必須是隱藏點上的最頂層表單。如果表單被其他表單遮擋,則它們將被包含在屏幕截圖中。我希望這不會成爲你的問題。

說明:如前所述,在Windows中實現透明的唯一方法是所有控件的全面合作,這是一項艱鉅的任務。其他任何東西(包括這個解決方案)都只是一種騙局。