.net 如何在 WinForms 中设置面板的不透明度或透明度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4463363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I set the opacity or transparency of a Panel in WinForms?
提问by Gian Santillan
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!
我想知道如何在 C# 中更改或修改面板的透明度,而不是整个表单,而只是面板。我正在寻找如何仅与小组合作。谢谢你!
采纳答案by Hans Passant
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.
是的,不透明度仅适用于顶级窗口。它使用视频适配器的硬件功能,不支持子窗口,如面板。Winforms 中唯一的顶级 Control 派生类是 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.
然而,一些“纯”Winform 控件(它们自己绘制而不是让本机 Windows 控件完成工作)确实支持透明的 BackColor。面板就是其中之一。它使用了一个技巧,它要求 Parent 自己绘制以生成背景像素。这个技巧的一个副作用是重叠控件不起作用,您只能看到父像素,而不是重叠控件。
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 :)
值得注意的是,Windows 8 中取消了此限制。它不再使用视频适配器覆盖功能,并且无法再关闭 DWM(又名 Aero)。这使得子窗口的不透明度/透明度易于实现。依靠这个当然是未来一段时间的音乐。Windows 7 将是下一个 XP :)
回答by Abdusalam Ben Haj
For whoever is still looking for a totally transparent panel, I found a nice solution in this blog by William Smashwho in turn has taken it from Tobias Hertkorn on his T# blog. I thought its worth posting it as an answer here.
对于仍在寻找完全透明面板的人,我在William Smash 的这篇博客中找到了一个不错的解决方案,他又从Tobias Hertkorn 的 T# 博客中获取了它。我认为值得在这里发布它作为答案。
C# code:
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 code:
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
回答by Brian Hasden
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.
根据在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);
}
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.
需要注意的是,添加到面板的任何控件都具有不透明的背景。尽管如此,半透明面板对我来说很有用,可以挡住我的 WinForms 应用程序的一部分,以便用户将注意力转移到应用程序的适当区域。
回答by Bill Moore
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
// <== 否则其他控件会在透明面板的顶部绘制
回答by Ignacio Soler Garcia
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.
据我所知,面板只能有透明颜色,您无法控制面板的不透明度。因此,您可以让面板的某些部分完全透明,但不能让 50% 的部分完全透明。
To use transparency you must define the transparent color property.
要使用透明度,您必须定义透明颜色属性。
回答by Dark Knight
Try this:
尝试这个:
panel1.BackColor = Color.FromArgb(100, 88, 44, 55);
change alpha(A) to get desired opacity.
更改 alpha(A) 以获得所需的不透明度。
回答by Mehdi Dehghani
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);
}
}
回答by Dan
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.
我只是想添加到 William Smash 解决方案中,因为我无法访问他的博客,因此无法找到可能存在于我的简单问题中的答案。
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.
如果您还没有这样做,您需要在项目属性中添加对 System.Windows.Forms 的引用。
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
对于 OnPaintBackground,您需要为 System.Drawing 添加一个引用,然后
Imports System.Drawing.Printing.PrintEventArgs
回答by Ahmed Taha
some comments says that it works and some say it doesn't
It works only for your formbackground not any other controlsbehind
一些评论说,它的工作原理,并有人说这不它仅适用于你的form背景没有任何其他controls背后
回答by umami
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.
这对我有用。在下面的例子中,Alpha 范围可以是 0 到 255 之间的一个值。以前,我认为它必须是百分比值,这是一个错误。
Dim x as integer = 230
Panel1.BackColor = Color.FromArgb(x, Color.Blue)
Dim x as integer = 230
Panel1.BackColor = Color.FromArgb(x, Color.Blue)

