2014-01-07 99 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

如果我不想让你(和其他人)使用它,我不会在这里发布它;) –

相关问题