具有不透明度的 WinForm 控件

发布于 2024-11-08 23:54:25 字数 1627 浏览 2 评论 0原文

我有一个本身有一些控件的表单(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;

}

这段代码隐藏了所有控件,但我不想隐藏表单上的控件。我想在它们上绘制一个深色层。并且用户必须可以看到控件。 我需要类似表单控件的不透明属性之类的东西。

我已经测试了这个:

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。

I have a form that has some controls on itself(btnCreateReport,pnlDarkLayer).I have a panel that fit to form(Dock = Fill) and it is on the back of all controls.when user click on the btnCreateReport button ,I call pnlDarkLayer BringToFront method and after some calculation I call SendToBack() method of the button.I want to draw a dark layer on form controls and disable all of controls on the form.
Is it possible? Thanks.

Maybe this code help u to understand my purpose:

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;

}

This code hide all of controls but i don't want to hide controls on the form.I want to draw a dark layer on them.And User must can see controls.
I need something like opacity property of forms for their controls.

I have test this:

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

Update: I have test this one: (use a form instead of panel)

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;

}

But I can't see the ProgressForm in my form.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

玉环 2024-11-15 23:54:25

来自 http:// support.microsoft.com/kb/943454

WinForms 中的透明控件是
相对于他们的父母是透明的,
不影响其他控件。透明度
WinForms 更类似于伪装
比真正的透明度。透明的
控制实际上并没有让你看到
其背后的控制通过
形式。它要求它的父级绘制它的
自己的背景就“透明”
控制。这就是为什么透明
控件显示其背后的形式,但是
覆盖任何其他控件。

实现相对于的透明度
其他控件也需要做同样的事情
但在更大范围内:相反
只是要求家长借鉴
前台控件的背景,
控件需要询问所有控件
在其后面绘制其背景。
这仅适用于以下控件
提供一些方法来请求
他们被吸引并且不会
时自动更新
背景控件的图像发生变化。

该页面还提供了一个代码示例(遗憾的是,在 vb 中)来展示这是如何完成的。

From http://support.microsoft.com/kb/943454

Transparent controls in WinForms are
transparent relative to their parent,
not to other controls. Transparency in
WinForms is more akin to camouflage
than true transparency. A transparent
control doesn’t actually let you see
the control behind it through the
form. It asks its parent to draw its
own background on the "transparent"
control. This is why a transparent
control shows the form behind it, but
covers up any other controls.

To implement transparency relative to
other controls requires doing the same
thing but on a larger scale: instead
of just asking the parent to draw on
the foreground control’s background,
the control needs to ask all controls
behind it to draw on its background.
This will only work for controls which
provide some method to request that
they be drawn and will not
automatically update when the
background control’s image changes.

The page also provides a code example (in vb, sadly) to show how this is done.

幸福丶如此 2024-11-15 23:54:25

如果我理解正确的话,您想在操作运行时将表单的内容“变暗”。

正如有人之前说过的,要做到正确是非常棘手的。但有一种方法可以轻松完成,只需进行一次预订(见下文)。

看一下这个源代码:

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()。

Shroud() 方法获取表单的快照,并将其复制到位图中,然后将其“变暗”。然后隐藏控件,并将位图绘制在窗体上。

UnShroud() 方法恢复控件,并告诉窗体不再绘制位图。

它需要两个私有变量:一个用于存储位图,另一个用于维护当前状态的标志。

它还重写了 OnPaint(),因为它需要在“隐藏”时绘制背景图像。

注意:屏蔽是通过截取表单的屏幕截图来实现的。这意味着该表单必须是覆盖点的最顶层表单。如果该表单被其他表单遮挡,那么它们将包含在屏幕截图中。我希望这对您来说不会成为问题。

注意:如前所述,在 Windows 中实现透明性的唯一方法是所有相关控件的充分合作,而这是一项艰巨的任务。其他任何东西(包括这个解决方案)实际上都只是骗局。

If I understand correctly, you want to 'darken' the contents of the form while an operation is running.

As someone's said before here, it's very tricky to do right. But there is a way to get it done easily, with one reservation (see below).

Look at this source code:

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;
    }
}

The Form1 class has two main methods, Shroud() and Unshroud().

The Shroud() method takes a snapshot of the form, and copies it into a bitmap, which is then 'darkened'. The controls are then hidden, and the bitmap is painted on the form.

The UnShroud() method restores the controls, and tells the form to no longer draw the bitmap.

It requires two private variables: one to store the bitmap, and a flag that maintains the current state.

It also overrides OnPaint() because it needs to draw the background image when it is 'shrouded'.

Note: The shrouding works by taking a screenshot of the form. This means that the form MUST BE the top-most form at the point of shrouding. If the form is obscured by other forms then they will be included in the screenshot. I hope that this won't be a problem for you.

Note: As said before, the only way to achieve transparency in Windows is full cooperation from all controls involved, and that's an arduous task. Anything else (including this solution) is really just trickery.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文