2014-01-07 139 views
2

我有一個簡單的Windows窗體。當用戶點擊一個按鈕時,會執行一個需要10-20秒的強烈計算。在此期間,我想用半透明的黑色覆蓋UI元素,以向用戶指示它們不能被點擊。我怎樣才能把着色器放在我的UI上

我試圖把一個小組在UI與背景色像這樣

mypanel.BackColor = Color.FromArgb(100, 0, 20, 0); 

但小組是固體和UI是不是背後可見。

我想我的用戶界面被黑色陰影,而不是可點擊。這可能嗎?我習慣於web開發,這種事情是標準和微不足道的,所以我有點困惑,它並不明顯。

謝謝!

+0

關於'A'值改變(100'')的東西像什麼'20'? –

+0

@HighCore讓面板更輕但不透明(這是它後面的控件不可見),alpha是0-256的比例,所以即使是100我也應該大部分看透。 – asutherland

+0

「BackColor屬性不支持透明顏色,除非System.Windows.Forms.ControlStyles的SupportsTransparentBackColor值設置爲true。」 - http://msdn.microsoft.com/en-us/library/system.windows.forms.control.backcolor(v=vs.110).aspx – mao47

回答

3

你可以做的是將表單的啓用屬性設置爲false,這將灰化表單中的所有控件。

例如:

private void button2_Click(object sender, EventArgs e) 
    { 
     this.Enabled = false; 
    } 

這一切確實是鎖定的形式,用戶將無法對它做任何事情。 當操作完成(或使用定時器)時,您需要做相反的操作並將enabled屬性設置爲true。

+0

不完全是我想到的,但這個作品,謝謝 – asutherland

1

不得不在類似的情況下處理winforms透明度,我發現的第一件事是:它不支持半透明(以一種簡單的方式)。
我最終深入研究了window styles(最重要的一個是WS_EX_LAYERED),並推出了我自己的控制。

大部分這方面的東西,我發現通過大量的谷歌搜索,並嘗試和錯誤...

讓我們去爲它:

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

public partial class ShaderControl : UserControl 
{ 

    //we will need all these imports, see their documentation on what they do exactly 
    [DllImport("user32")] 
    private static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 
    [DllImport("user32")] 
    private static extern int ShowWindow(IntPtr hWnd, int nCmdShow); 
    [DllImport("user32", EntryPoint = "SetWindowLong", SetLastError = true)] 
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); 
    [DllImport("user32", EntryPoint = "SetLayeredWindowAttributes")] 
    private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags); 
    [DllImport("user32", EntryPoint = "GetWindowLong", SetLastError = true)] 
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex); 

    //we're going to give the window these constans as parameters 
    private const int WS_EX_TOOLWINDOW = 0x80; //make it a toolwindow 
    private const int WS_EX_NOACTIVATE = 0x8000000; //make it non-activating 
    private const int WS_EX_TOPMOST = 0x8; //make it the topmost window 

    //and we need these ones later on, too to achieve semi-transparency 
    private const int GWL_EXSTYLE = -20; 
    private const int WS_EX_LAYERED = 0x80000; 
    private const int LWA_ALPHA = 0x2; 

    private double opacity = 0.8; //between 0 and 1 

    public ShaderControl() 
    { 
     InitializeComponent(); 
    } 

    protected override CreateParams CreateParams 
    { 
     //here we create the window parameters 
     //this will be called once when the window is created 
     get 
     { 
      CreateParams p = base.CreateParams; 
      p.ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST); 
      return p; 
     } 
    } 

    public new void Show() 
    { 
     //here we make the window a child of the desktop 
     if (this.Handle == IntPtr.Zero) 
     { 
      base.CreateControl(); 
     } 
     SetParent(base.Handle, IntPtr.Zero); 
     ShowWindow(base.Handle, 1); 
    } 

    protected sealed override void OnVisibleChanged(EventArgs e) 
    { 
     base.OnVisibleChanged(e); 

     if (this.Visible) 
     { 
      //every time the window gets shown we have to update the window attributes 
      //the important thing here is the WS_EX_LAYERED attribute, this makes it possible to achieve semi-transparency 
      int wl = GetWindowLong(this.Handle, GWL_EXSTYLE); 
      wl = wl | WS_EX_LAYERED; 
      SetWindowLong(this.Handle, GWL_EXSTYLE, wl); 
      SetLayeredWindowAttributes(this.Handle, 0, (byte)(opacity * 255), LWA_ALPHA); 
     } 
    } 

    public double Opacity 
    { 
     get 
     { 
      return opacity; 
     } 
     set 
     { 
      //when the opacity changes we have to renew the window attributes 
      opacity = value > 0d ? Math.Min(1d, value) : Math.Max(0d, value); 
      SetLayeredWindowAttributes(this.Handle, 0, (byte)(opacity * 255), LWA_ALPHA); 
     } 
    } 
} 

現在所有的留給你的是設置ShaderControl.Opacity的值0和1之間,適合您的需求和 - 最重要的 - 給這個控制正確的大小和位置

延伸閱讀:
vbaccelerator.com - Floating Control
codeproject.com - Microsoft WORD 2007 Style Semi transparent Minibar
Topmost form, clicking "through" possible?

+0

哇這可能是真棒,今晚會嘗試它,謝謝! – asutherland

+0

此外,假設我可以得到這個工作,你介意,如果我或多或少地使用這個是嗎?它可以是MIT許可證嗎? – asutherland

+0

如果我不想讓你(和其他人)使用它,我不會在這裏發佈它;) –

相關問題