C# Windows 窗体半透明
Posted
技术标签:
【中文标题】C# Windows 窗体半透明【英文标题】:C# Windows Forms semi-opacity 【发布时间】:2018-12-03 08:41:05 【问题描述】:我已经阅读了很多关于 C# 中 Windows 窗体的不透明度/透明度的主题,但这不是我想要的效果。我希望Form
是 100% 透明的,但 Panel
的透明度是可调节的,并且透明效果被转移到 Form 后面的元素(Windows 桌面、Web 浏览器等)。所附照片显示了我想要获得的效果(我在图形程序中制作它们)。我会很感激你的帮助。
【问题讨论】:
每个面板都可以是由Form1
拥有的***无边框Form
。 Form1
具有与其背景颜色相同的透明度键,并且那些拥有的表单具有不透明度。
这个想法看起来不错,但不幸的是它不起作用。我不知道我是否理解得很好。我这样做是为了设置 Form1.IsMdiContainer = true 和 Form1.TransparencyKey = Color.FromArgb(171, 171, 171) (当 Form 为 MdiContainer 时等于背景颜色)。不幸的是,这并没有给出预期的结果,因为 Form1 不透明。我不知道 Form1 是 IsMdiContainer 时透明度是否不起作用。除非我做了 Form1 拥有的 Form2,否则 Form2 参数 Opacity 不会改变 Form2 的透明度。
拥有的表单与 MDIchildren 不同。它们不是以所有者形式托管的。他们只是在所有者表格之上。你应该把它们放在一起。
您的另一个选择是使用layered windows。这样,您可以在运行时创建半透明图像并将其设置为表单的背景图像。但是您的表单将不会收到任何绘制事件,因此在此类表单上托管控件毫无意义(但是您可以通过某种方式使这些控件正常工作)。
根据你这里的评论→OP:如果有其他语言/环境可以处理>这个问题,我当然准备试试。 i> 我建议你使用WPF
。
【参考方案1】:
面板没有 opacity 属性。为了使面板透明,您应该使用这样的自定义面板...
Imports System.ComponentModel
Partial Public Class C_PANEL
Inherits Panel
Private Const WS_EX_TRANSPARENT As Integer = &H20
Public Sub NewP()
SetStyle(ControlStyles.Opaque, True)
End Sub
Public Sub NewP(con As IContainer)
con.Add(Me)
End Sub
Private iopacity As Integer = 50
<DefaultValue(50)>
Public Property Opacity() As Integer
Get
Return Me.iopacity
End Get
Set(value As Integer)
If Value < 0 OrElse Value > 100 Then
Throw New ArgumentException("value must be between 0 and 100")
End If
Me.iopacity = Value
End Set
End Property
Protected Overrides ReadOnly Property CreateParams() _
As CreateParams
Get
Dim cpar As CreateParams = MyBase.CreateParams
cpar.ExStyle = cpar.ExStyle Or WS_EX_TRANSPARENT
Return cpar
End Get
End Property
Protected Overrides Sub OnPaint(e As PaintEventArgs)
Using brush = New SolidBrush(Color.FromArgb(Me.Opacity _
* 255 / 100, Me.BackColor))
e.Graphics.FillRectangle(brush, Me.ClientRectangle)
End Using
MyBase.OnPaint(e)
End Sub
End Class
创建此控件后,您可以将此面板添加到表单中,并可以根据您的设置设置不透明度。
并且表单有自己的 opacity 属性,可以轻松设置。
【讨论】:
问题标记为 C#,而不是 VB。 您可以使用 carlosag 转换器将此代码转换为 c# 代码。我认为这个想法足以解决问题而不是代码.. ;) 没错,问题是关于 C#,而不是 VB,但没关系,因为我在 C# 中看到了相同的解决方案,但它并没有像我想要的那样工作。使用此解决方案,透明度仅适用于本地,仅适用于 Form 上的元素。整个 Panel 对桌面不透明。下面我附上这个解决方案的外观。 link “问题是关于 C#,而不是 VB”@grzenio_l,你的问题围绕着操纵 WinForm 控件来达到预期的效果。用于实现该解决方案的 .Net 语言应该是无关紧要的。为什么你会选择限制获得解决方案的可能性只是为了强加个人偏好? 我将使用哪种语言并不重要。我正在学习使用 C# 语言,因为我有使用 C 和 C++ 编写微控制器的经验,而 C# 最接近这种语言。如果有其他语言/环境我可以处理这个问题,当然我准备尝试一下,虽然VB语言的语法对我来说不是很清楚,我宁愿避免。【参考方案2】:OP: 如果有其他语言/环境我可以处理 这个问题,我当然准备试试了。
所以除了 Windows Forms 解决方案之外,我还会分享一个 WPF 解决方案(这是一个更好的框架来满足这个要求):
Windows 窗体 - 拥有的窗体 Windows 窗体 - 分层窗口 WPF - 透明表单和控制不透明度Windows 窗体 - 拥有的窗体
作为一个选项,您可以使用自有表单。
每个面板都可以是主窗体拥有的***无边框窗体。主窗体具有与其背景颜色相同的透明度键,而那些拥有的窗体具有不透明度。这样,您应该处理主表单的移动并同时移动拥有的表单:
public partial class MyOwnerForm : Form
public MyOwnerForm()
InitializeComponent();
this.BackColor = Color.Magenta;
this.TransparencyKey = Color.Magenta;
this.StartPosition = FormStartPosition.Manual;
this.DesktopLocation = new Point(100, 100);
this.ClientSize = new Size(330, 330);
protected override void OnShown(EventArgs e)
base.OnShown(e);
CreateForm(1, new Point(10, 10), new Size(150, 150)).Show();
CreateForm(0.75, new Point(170, 10), new Size(150, 150)).Show();
CreateForm(0.50, new Point(10, 170), new Size(150, 150)).Show();
CreateForm(0.25, new Point(170, 170), new Size(150, 150)).Show();
protected override void OnMove(EventArgs e)
base.OnMove(e);
if(OwnedForms.Length>0)
var p = PointToScreen(new Point(10, 10));
var dx = p.X - OwnedForms[0].Location.X;
var dy = p.Y - OwnedForms[0].Location.Y;
foreach (var f in OwnedForms)
f.Location= new Point(f.Location.X+dx, f.Location.Y+dy);
Form CreateForm(double opacity, Point location, Size size)
var f = new Form();
f.FormBorderStyle = FormBorderStyle.None;
f.BackColor = Color.Lime;
f.Opacity = opacity;
f.StartPosition = FormStartPosition.Manual;
f.DesktopLocation = PointToScreen(location);
f.ClientSize = size;
f.Owner = this;
f.ShowInTaskbar = false;
return f;
Windows 窗体 - 分层窗口
作为一个选项,您可以使用Layered Windows。
这样您可以在运行时创建半透明图像并将其设置为表单的背景图像。但是您的表单不会收到任何绘制事件,因此在此类表单上托管控件是没有意义的(但是它们正在工作并且您可以以某种方式强制这些控件重新绘制)。
public partial class MyLayeredForm : PerPixelAlphaForm
public MyLayeredForm()
InitializeComponent();
var bm = new Bitmap(230, 230);
using (var g = Graphics.FromImage(bm))
using (var b = new SolidBrush(Color.FromArgb(255, Color.Lime)))
g.FillRectangle(b, 10, 10, 100, 100);
using (var b = new SolidBrush(Color.FromArgb(255 * 75 / 100, Color.Lime)))
g.FillRectangle(b, 120, 10, 100, 100);
using (var b = new SolidBrush(Color.FromArgb(255 * 50 / 100, Color.Lime)))
g.FillRectangle(b, 10, 120, 100, 100);
using (var b = new SolidBrush(Color.FromArgb(255 * 25 / 100, Color.Lime)))
g.FillRectangle(b, 120, 120, 100, 100);
this.SelectBitmap(bm);
WPF - 具有不透明度的透明表单和控件
满足此类 UI 要求的更好框架是 WPF。
为此,您可以将窗口的Background
设置为Transparent
,将WindowStyle
设置为None
,并将AllowTransparency
设置为True
。同样对于每个控件,您可以简单地设置Opacity
值:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="261.154" Width="232.923"
Background="Transparent" AllowsTransparency="True"
WindowStyle="None" WindowStartupLocation="CenterScreen">
<Grid Margin="0,0,0,0">
<Grid HorizontalAlignment="Left" Height="100"
Margin="10,10,0,0" VerticalAlignment="Top"
Width="100" Background="Lime" Opacity="1"/>
<Grid HorizontalAlignment="Left" Height="100"
Margin="120,10,0,0" VerticalAlignment="Top"
Width="100" Background="Lime" Opacity="0.75"
Grid.ColumnSpan="2"/>
<Grid HorizontalAlignment="Left" Height="100"
Margin="10,120,0,0" VerticalAlignment="Top"
Width="100" Background="Lime" Opacity="0.50"/>
<Grid HorizontalAlignment="Left" Height="100"
Margin="120,120,0,0" VerticalAlignment="Top"
Width="100" Background="Lime" Opacity="0.25"
Grid.ColumnSpan="2"/>
</Grid>
</Window>
【讨论】:
非常感谢您的帮助,您给了我很多有用的信息。对于我的项目,我不需要使用控件(按钮、文本框),因此“Windows 窗体 - 分层 Windows”解决方案可能很好。我已经尝试过这个解决方案并且效果很好,但是当我下班回家时我会对其进行更多测试。我也会尝试“WPF”。不幸的是,我的评分没有足够的声誉被包括在内。 不客气。不用担心,通过提出好问题或分享好答案,您将获得更多声誉。 和 *** 一样,我们周围有一些不可见的反对者! 我认为不仅在***上:P 好的,@RezaAghaei,我知道这是一篇旧帖子。我使用 PixelPerAlpha 版本来显示我的启动画面。如何使用该表单的标签来显示一些进展?我的意思是显示一个标签并能够从主窗体更改其文本。怎么重画?!您在回答中这么说!以上是关于C# Windows 窗体半透明的主要内容,如果未能解决你的问题,请参考以下文章
delphi 怎样绘制半透明窗体,只让窗体背景半透明,而窗体里面的控件 不透明