带不透明度的WinForm控件

问题描述

| 我有一个本身具有某些控件的表单(btnCreateReport,pnlDarkLayer)。我有一个适合表单的面板(Dock = Fill),它位于所有控件的背面。当用户单击btnCreateReport按钮时,我称pnlDarkLayer BringToFront方法,经过一番计算后,我调用了按钮的SendToBack()方法,我想在表单控件上绘制一个深色层,并禁用表单上的所有控件。 可能吗?谢谢。 也许这段代码可以帮助您了解我的目的:
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隐藏控件希望借助them.And用户深色层必须可以看到控制。 我需要类似控件的表单的不透明度属性。 我已经测试过了:
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。     

解决方法

来自
http://support.microsoft.com/kb/943454
  WinForms中的透明控件是   相对于父母透明   而不是其他控件。透明   WinForms更类似于伪装   比真正的透明度。透明的   控件实际上并没有让您看到   通过它背后的控制   形成。它要求其父母画出   自己在“透明”上的背景   控制。这就是为什么透明   控件显示其背后的形式,但是   掩盖了其他所有控件。      相对于实现透明   其他控件也需要这样做   事,但规模更大:相反   只是要求父母画画   前台控件的背景,   控件需要询问所有控件   在它后面绘制背景。   这仅适用于   提供一些方法来要求   他们被吸引,不会   自动更新时   后台控件的图像更改。 该页面还提供了一个代码示例(可悲的是,在vb中),以显示此操作的完成方式。     ,如果我理解正确,那么您想在操作运行时“使”表单的内容“变暗”。 正如之前有人说的那样,正确做事非常棘手。但是有一种方法可以轻松完成,只需保留一次即可(请参见下文)。 看下面的源代码:
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);
    }

    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,area.Width,area.Height);
        g.Dispose();

        _background = screenGrab;
    }
}
Form1类有两个主要方法,Shroud()和Unshroud()。 所述导流罩()方法采用的形式的快照,并把它拷贝成位图,然后将其\“变暗\”。然后隐藏控件,并将位图绘制在窗体上。 UnShroud()方法还原控件,并通知表单不再绘制位图。 它需要两个私有变量:一个用于存储位图,另一个用于维护当前状态。 它还覆盖了OnPaint(),因为当它被“遮盖”时,它需要绘制背景图像。 注意:遮罩的工作原理是截取表单的屏幕截图。这意味着,在覆盖时,表单必须是最上面的表单。如果该表单被其他表单遮盖,则它们将包含在屏幕截图中。希望对您来说不会有问题。 注:正如前面所说,在Windows中实现透明度的唯一途径是从所涉及的所有控件充分合作,而且\'S艰巨的任务。其他任何东西(包括此解决方案)实际上都是骗局。     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...