C# 使用一些控件在整个窗口窗体上绘制半透明覆盖图像
在具有某些控件的windows窗体上绘制半透明覆盖图像,以便其所有子控件都应可见,但不能单击它们。这就像我们通过半透明的黑色镜子看到一些东西一样 我尝试过使用透明控件。这是对面板控件和该控件上的绘图图像进行子分类,但是所有控件都完全可见。创建一个保持在主窗体顶部并与其位置同步的控件。您可以使用32位RGBA图像更改分层窗口的alpha,以获得所需的效果C# 使用一些控件在整个窗口窗体上绘制半透明覆盖图像,c#,overlay,transparent,C#,Overlay,Transparent,在具有某些控件的windows窗体上绘制半透明覆盖图像,以便其所有子控件都应可见,但不能单击它们。这就像我们通过半透明的黑色镜子看到一些东西一样 我尝试过使用透明控件。这是对面板控件和该控件上的绘图图像进行子分类,但是所有控件都完全可见。创建一个保持在主窗体顶部并与其位置同步的控件。您可以使用32位RGBA图像更改分层窗口的alpha,以获得所需的效果 有一篇像样的codeproject文章向您展示了如何做到这一点。这需要在现有表单之上显示另一个表单。其不透明度属性可以创建预期效果。向项目中添加
有一篇像样的codeproject文章向您展示了如何做到这一点。这需要在现有表单之上显示另一个表单。其不透明度属性可以创建预期效果。向项目中添加一个新类并粘贴如下所示的代码。调用Close()方法再次移除效果
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class Plexiglass : Form {
public Plexiglass(Form tocover) {
this.BackColor = Color.DarkGray;
this.Opacity = 0.30; // Tweak as desired
this.FormBorderStyle = FormBorderStyle.None;
this.ControlBox = false;
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.Manual;
this.AutoScaleMode = AutoScaleMode.None;
this.Location = tocover.PointToScreen(Point.Empty);
this.ClientSize = tocover.ClientSize;
tocover.LocationChanged += Cover_LocationChanged;
tocover.ClientSizeChanged += Cover_ClientSizeChanged;
this.Show(tocover);
tocover.Focus();
// Disable Aero transitions, the plexiglass gets too visible
if (Environment.OSVersion.Version.Major >= 6) {
int value = 1;
DwmSetWindowAttribute(tocover.Handle, DWMWA_TRANSITIONS_FORCEDISABLED, ref value, 4);
}
}
private void Cover_LocationChanged(object sender, EventArgs e) {
// Ensure the plexiglass follows the owner
this.Location = this.Owner.PointToScreen(Point.Empty);
}
private void Cover_ClientSizeChanged(object sender, EventArgs e) {
// Ensure the plexiglass keeps the owner covered
this.ClientSize = this.Owner.ClientSize;
}
protected override void OnFormClosing(FormClosingEventArgs e) {
// Restore owner
this.Owner.LocationChanged -= Cover_LocationChanged;
this.Owner.ClientSizeChanged -= Cover_ClientSizeChanged;
if (!this.Owner.IsDisposed && Environment.OSVersion.Version.Major >= 6) {
int value = 1;
DwmSetWindowAttribute(this.Owner.Handle, DWMWA_TRANSITIONS_FORCEDISABLED, ref value, 4);
}
base.OnFormClosing(e);
}
protected override void OnActivated(EventArgs e) {
// Always keep the owner activated instead
this.BeginInvoke(new Action(() => this.Owner.Activate()));
}
private const int DWMWA_TRANSITIONS_FORCEDISABLED = 3;
[DllImport("dwmapi.dll")]
private static extern int DwmSetWindowAttribute(IntPtr hWnd, int attr, ref int value, int attrLen);
}
我认为更简单的方法是放置一个透明标签控件,在其中设置其不透明度,并禁用其自动调整大小功能,并将标签调整为要覆盖的曲面的大小 然后,当您想要覆盖标签时,可以将其发送到前端(以编程方式)并使其可见。如果要禁用覆盖,请将其发送到背面并使其不可见
我用一个覆盖整个表单的文本标签完成了这项工作。如果不设置Label控件的Text属性,而是设置一个半透明(PNG)图像,我认为效果也一样。这个类的确切名称是什么?看起来像是
Utils.Plexiglass(this)代码>。。。ALT+F4将关闭它。有没有办法在窗口顶部显示黑色文本,例如“请稍候”?(我刚刚将不透明度增加了三倍,并在这个覆盖层中添加了一个动态标签)嘿,皮特,我想知道你是如何在有机玻璃上显示标签的?有什么建议吗?:)@HansPassant,这个答案非常有用,但它似乎也使子控件(即标签文本)半透明。有没有一种方法可以让窗体半透明,而它的子对象是完全不透明的?谢谢。当然,不透明就是这样做的。此类仅适用于覆盖现有窗口,“应该是可见的,但您不能按OP的要求单击它们”,但不适用于显示任何UI。