如何在 WinForms 中设置面板的不透明度或透明度?

发布于 2024-10-08 15:13:58 字数 95 浏览 6 评论 0原文

我想知道如何更改或修改 C# 中面板的透明度,而不是整个表单,而只是面板。我看过很多关于不透明度的 C# 教程,但它是针对表单的。我正在寻找如何仅通过面板来实现这一点。谢谢你!

I was wondering how to change or modify the transparency of a Panel in C#, not the whole form, but the panel only.. I've seen many C# tutorials on Opacity, but its for the Form. im looking for how it could be possible with the Panel only. Thank You!

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

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

发布评论

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

评论(10

还在原地等你 2024-10-15 15:13:59

对于仍在寻找完全透明面板的人,我在 William Smash 的博客中找到了一个很好的解决方案他又从 Tobias Hertkorn 那里获取了它在他的 T# 博客 上。我认为值得将其作为答案发布在这里。

C# 代码:

public class TransparentPanel : Panel
{
    protected override CreateParams CreateParams 
    {            
        get {
            CreateParams cp =  base.CreateParams;
            cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
            return cp;
            }
    }
    protected override void OnPaintBackground(PaintEventArgs e) 
    {
        //base.OnPaintBackground(e);
    }
}

VB.Net 代码:

Public Class TransparentPanel
Inherits Panel
    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or &H20 ''#WS_EX_TRANSPARENT
            Return cp
        End Get
    End Property
    Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
    ''#MyBase.OnPaintBackground(e)
    End Sub
End Class

For whoever is still looking for a totally transparent panel, I found a nice solution in this blog by William Smash who in turn has taken it from Tobias Hertkorn on his T# blog. I thought its worth posting it as an answer here.

C# code:

public class TransparentPanel : Panel
{
    protected override CreateParams CreateParams 
    {            
        get {
            CreateParams cp =  base.CreateParams;
            cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
            return cp;
            }
    }
    protected override void OnPaintBackground(PaintEventArgs e) 
    {
        //base.OnPaintBackground(e);
    }
}

VB.Net code:

Public Class TransparentPanel
Inherits Panel
    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or &H20 ''#WS_EX_TRANSPARENT
            Return cp
        End Get
    End Property
    Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
    ''#MyBase.OnPaintBackground(e)
    End Sub
End Class
沉睡月亮 2024-10-15 15:13:59

是的,不透明度只能在顶级窗口上起作用。它使用视频适配器的硬件功能,不支持子窗口,例如面板。 Winforms 中唯一的顶级 Control 派生类是 Form。

然而,一些“纯”Winform 控件(它们自己进行绘制而不是让本机 Windows 控件完成这项工作)确实支持透明的背景色。面板就是其中之一。它使用了一个技巧,它要求父级绘制自己以产生背景像素。这一技巧的一个副作用是重叠控件不起作用,您只能看到父像素,而看不到重叠的控件。

此示例表单展示了它的工作情况:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        this.BackColor = Color.White;
        panel1.BackColor = Color.FromArgb(25, Color.Black);
    }
    protected override void OnPaint(PaintEventArgs e) {
        e.Graphics.DrawLine(Pens.Yellow, 0, 0, 100, 100);
    }
}

如果这还不够好,那么您需要考虑将表单堆叠在一起。 这样

值得注意的是,Windows 8 中取消了此限制。它不再使用视频适配器覆盖功能,并且无法再关闭 DWM(又名 Aero)。这使得子窗口的不透明度/透明度很容易实现。依靠这一点当然是未来的音乐。 Windows 7 将成为下一个 XP :)

Yes, opacity can only work on top-level windows. It uses a hardware feature of the video adapter, that doesn't support child windows, like Panel. The only top-level Control derived class in Winforms is Form.

Several of the 'pure' Winform controls, the ones that do their own painting instead of letting a native Windows control do the job, do however support a transparent BackColor. Panel is one of them. It uses a trick, it asks the Parent to draw itself to produce the background pixels. One side-effect of this trick is that overlapping controls doesn't work, you only see the parent pixels, not the overlapped controls.

This sample form shows it at work:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        this.BackColor = Color.White;
        panel1.BackColor = Color.FromArgb(25, Color.Black);
    }
    protected override void OnPaint(PaintEventArgs e) {
        e.Graphics.DrawLine(Pens.Yellow, 0, 0, 100, 100);
    }
}

If that's not good enough then you need to consider stacking forms on top of each other. Like this.

Notable perhaps is that this restriction is lifted in Windows 8. It no longer uses the video adapter overlay feature and DWM (aka Aero) cannot be turned off anymore. Which makes opacity/transparency on child windows easy to implement. Relying on this is of course future-music for a while to come. Windows 7 will be the next XP :)

浪菊怪哟 2024-10-15 15:13:59

基于 http://www.windows-tech.info/3/53ee08e46d9cb138 中找到的信息。 php,我能够使用以下代码实现半透明面板控件。

public class TransparentPanel : Panel
{
    protected override CreateParams CreateParams
    {
        get
        {
            var cp = base.CreateParams;
            cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT

            return cp;
        }
    }

    protected override void OnPaint(PaintEventArgs e) =>
        e.Graphics.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle);
}

需要注意的是,添加到面板的任何控件都有不透明的背景。尽管如此,半透明面板对我来说很有用,它可以遮挡我的 WinForms 应用程序的某些部分,以便用户将焦点转移到应用程序的适当区域。

Based on information found at http://www.windows-tech.info/3/53ee08e46d9cb138.php, I was able to achieve a translucent panel control using the following code.

public class TransparentPanel : Panel
{
    protected override CreateParams CreateParams
    {
        get
        {
            var cp = base.CreateParams;
            cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT

            return cp;
        }
    }

    protected override void OnPaint(PaintEventArgs e) =>
        e.Graphics.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle);
}

The caveat is that any controls that are added to the panel have an opaque background. Nonetheless, the translucent panel was useful for me to block off parts of my WinForms application so that users focus was shifted to the appropriate area of the application.

阳光下的泡沫是彩色的 2024-10-15 15:13:59

试试这个:

panel1.BackColor = Color.FromArgb(100, 88, 44, 55);

更改 alpha(A) 以获得所需的不透明度。

Try this:

panel1.BackColor = Color.FromArgb(100, 88, 44, 55);

change alpha(A) to get desired opacity.

情绪 2024-10-15 15:13:59

具有不透明度的面板:

public class GlassyPanel : Panel
{
    const int WS_EX_TRANSPARENT = 0x20;  

    int opacity = 50;

    public int Opacity
    {
        get
        {
            return opacity;
        }
        set
        {
            if (value < 0 || value > 100) throw new ArgumentException("Value must be between 0 and 100");
            opacity = value;
        }
    }

    protected override CreateParams CreateParams
    {
        get
        {
            var cp = base.CreateParams;
            cp.ExStyle = cp.ExStyle | WS_EX_TRANSPARENT;

            return cp;
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        using (var b = new SolidBrush(Color.FromArgb(opacity * 255 / 100, BackColor)))
        {
            e.Graphics.FillRectangle(b, ClientRectangle);
        }

        base.OnPaint(e);
    }
}

Panel with opacity:

public class GlassyPanel : Panel
{
    const int WS_EX_TRANSPARENT = 0x20;  

    int opacity = 50;

    public int Opacity
    {
        get
        {
            return opacity;
        }
        set
        {
            if (value < 0 || value > 100) throw new ArgumentException("Value must be between 0 and 100");
            opacity = value;
        }
    }

    protected override CreateParams CreateParams
    {
        get
        {
            var cp = base.CreateParams;
            cp.ExStyle = cp.ExStyle | WS_EX_TRANSPARENT;

            return cp;
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        using (var b = new SolidBrush(Color.FromArgb(opacity * 255 / 100, BackColor)))
        {
            e.Graphics.FillRectangle(b, ClientRectangle);
        }

        base.OnPaint(e);
    }
}
私藏温柔 2024-10-15 15:13:59

在表单构造函数中动态创建面板时,不要忘记将面板置于最前面。选项卡控件的透明面板覆盖示例。

panel1 = new TransparentPanel();
panel1.BackColor = System.Drawing.Color.Transparent;
panel1.Location = new System.Drawing.Point(0, 0);
panel1.Name = "panel1";
panel1.Size = new System.Drawing.Size(717, 92);
panel1.TabIndex = 0;
tab2.Controls.Add(panel1);
panel1.BringToFront(); 

// <== 否则其他控件将在透明面板顶部绘制

Don't forget to bring your Panel to the Front when dynamically creating it in the form constructor. Example of transparent panel overlay of tab control.

panel1 = new TransparentPanel();
panel1.BackColor = System.Drawing.Color.Transparent;
panel1.Location = new System.Drawing.Point(0, 0);
panel1.Name = "panel1";
panel1.Size = new System.Drawing.Size(717, 92);
panel1.TabIndex = 0;
tab2.Controls.Add(panel1);
panel1.BringToFront(); 

// <== otherwise the other controls paint over top of the transparent panel

嘴硬脾气大 2024-10-15 15:13:59

据我所知,面板只能有透明颜色,您无法控制面板的不透明度。因此,您可以让面板的某些部分完全透明,但不能让 50% 的部分显示内容。

要使用透明度,您必须定义透明颜色属性。

As far as I know a Panel can have a transparent color only, you can not control the opacity of the panel. So, you can have some parts of a panel completely transparent but not a 50% to say something.

To use transparency you must define the transparent color property.

妳是的陽光 2024-10-15 15:13:59

我只是想添加 William Smash 的解决方案,因为我无法访问他的博客,因此找不到我的简单问题的答案。

我花了一段时间才意识到,但也许我只是有一段时间...

如果您还没有这样做,您将需要在项目属性中添加对 System.Windows.Forms 的引用。

此外,您还需要添加

Imports System.Windows.Forms 

到要添加覆盖类的文件中。

对于 OnPaintBackground,您需要添加 System.Drawing 的引用

Imports System.Drawing.Printing.PrintEventArgs

I just wanted to add to the William Smash solution as I couldn't get to his blog so answers which may have been in there to my simple questions could not be found.

Took me a while to realise, but maybe I was just having a moment...

If you haven't had to do so already you'll need to add a reference to System.Windows.Forms in the project properties.

Also you'll need to add

Imports System.Windows.Forms 

to the file where you're adding the override class.

For OnPaintBackground you'll need to add a reference for System.Drawing then

Imports System.Drawing.Printing.PrintEventArgs
风吹雨成花 2024-10-15 15:13:59

有的评论说有效,有的说不行
它仅适用于您的form背景,不适用于后面的任何其他control

some comments says that it works and some say it doesn't
It works only for your form background not any other controls behind

酒中人 2024-10-15 15:13:59

这对我有用。
在下面的示例中,Alpha 范围可以是 0 到 255 之间的值。
以前,我犯了一个错误,认为它一定是百分比值。

将 x 变暗为整数 = 230
Panel1.BackColor = Color.FromArgb(x, Color.Blue)

This does work for me.
In below example, Alpha range can be a value between 0 to 255.
Previously, I made a mistake by thinking that it must be a value of percentage.

Dim x as integer = 230
Panel1.BackColor = Color.FromArgb(x, Color.Blue)

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