首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >.NET Windows窗体透明控件

.NET Windows窗体透明控件
EN

Stack Overflow用户
提问于 2008-09-16 14:35:16
回答 5查看 13K关注 0票数 15

我想在Windows Forms应用程序中模拟“Web2.0”Lightbox风格的UI技术。也就是说,通过“调暗”窗口客户区中的所有其他内容来将注意力吸引到一些前景控件上。

显而易见的解决方案是创建一个控件,它只是一个部分透明的矩形,可以停靠到窗口的工作区,并放在Z顺序的前面。它需要表现得像一个肮脏的玻璃之痛,通过它仍然可以看到其他控件(并因此继续绘制自己)。这个是可能的吗?

我进行了一次很好的搜寻,并尝试了一些技巧,但到目前为止还没有成功。如果这是不可能的,还有什么方法可以做到呢?

参见:http://www.useit.com/alertbox/application-design.html (在Lightbox部分下面提供了一个屏幕截图来说明我的意思)。

EN

回答 5

Stack Overflow用户

发布于 2008-09-16 14:52:19

你能在.NET/C#中做到这一点吗?

是的,你当然可以,但这需要一点努力。我推荐以下方法。创建一个没有边框或标题栏区域的顶层窗体,然后通过将TransparencyKey和BackColor设置为相同的值,确保它不绘制客户区背景。所以你现在有了一个什么都没画的窗口。

代码语言:javascript
复制
public class DarkenArea : Form
{
    public DarkenArea()
    {
        FormBorderStyle = FormBorderStyle.None;
        SizeGripStyle = SizeGripStyle.Hide;
        StartPosition = FormStartPosition.Manual;
        MaximizeBox = false;
        MinimizeBox = false;
        ShowInTaskbar = false;
        BackColor = Color.Magenta;
        TransparencyKey = Color.Magenta;
        Opacity = 0.5f;
    }
}

创建此DarkenArea窗口并将其放置在窗体的工作区上。然后,您需要能够在不获取焦点的情况下显示窗口,因此您将需要以以下方式进行平台调用,以在不激活窗口的情况下进行显示……

代码语言:javascript
复制
public void ShowWithoutActivate()
{
    // Show the window without activating it (i.e. do not take focus)
    PlatformInvoke.ShowWindow(this.Handle, (short)SW_SHOWNOACTIVATE);
}

你需要让它实际绘制一些东西,但排除在你想要保持高亮显示的控件区域中的绘制。因此,覆盖OnPaint处理程序,绘制黑色/蓝色或任何你想要的,但不包括你想要保持明亮的区域…

代码语言:javascript
复制
protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    // Do your painting here be exclude the area you want to be brighter
}

最后,如果用户尝试一些疯狂的操作,比如单击变暗的区域,您需要覆盖WndProc以防止鼠标与窗口交互。就像这样..。

代码语言:javascript
复制
protected override void WndProc(ref Message m)
{
    if (m.Msg == (int)WM_NCHITTEST)
        m.Result = (IntPtr)HTTRANSPARENT;
    else
        base.WndProc(ref m);
}

这应该足以获得所需的效果。当您准备好反转效果时,您可以处理DarkenArea实例并继续。

票数 15
EN

Stack Overflow用户

发布于 2008-10-04 06:12:07

这是一个非常酷的想法--我可能会用到它,所以谢谢。不管怎样,我的解决方案很简单...在当前窗体上打开一个50%不透明的新窗体,然后自定义地为该窗体绘制一个背景图像,其中的矩形与您要突出显示的控件的边界相匹配,并以透明键的颜色填充。

在我的粗略示例中,我将这个表单称为“LBform”,其实质是:

代码语言:javascript
复制
public Rectangle ControlBounds { get; set; }
private void LBform_Load(object sender, EventArgs e)
{
    Bitmap background = new Bitmap(this.Width, this.Height);
    Graphics g = Graphics.FromImage(background);
    g.FillRectangle(Brushes.Fuchsia, this.ControlBounds);

    g.Flush();

    this.BackgroundImage = background;
    this.Invalidate();
}

Color.Fuchia是这个半透明窗体的TransparencyKey,因此您将能够看到绘制的矩形,并与其在主窗体上的边界内的任何内容交互。

在我提出的实验项目中,我使用了一个动态添加到窗体中的UserControl,但您也可以很容易地使用窗体上已有的控件。在主窗体(您正在隐藏的窗体)中,我将相关代码放入一个按钮中,单击:

代码语言:javascript
复制
private void button1_Click(object sender, EventArgs e)
{
    // setup user control:
    UserControl1 uc1 = new UserControl1();
    uc1.Left = (this.Width - uc1.Width) / 2;
    uc1.Top = (this.Height - uc1.Height) / 2;
    this.Controls.Add(uc1);
    uc1.BringToFront();

    // load the lightbox form:
    LBform lbform = new LBform();
    lbform.SetBounds(this.Left + 8, this.Top + 30, this.ClientRectangle.Width, this.ClientRectangle.Height);
    lbform.ControlBounds = uc1.Bounds;

    lbform.Owner = this;
    lbform.Show();
}

非常基本的东西,如果你喜欢,你可以用你自己的方式来做,但它只是添加用户控件,然后在主窗体上设置lightbox窗体,并设置bounds属性以在正确的位置呈现完整的透明度。在我的快速示例中没有处理表单拖拽和关闭lightbox表单和UserControl之类的事情。哦,别忘了处理Graphics实例--我也遗漏了这个(很晚了,我真的很累)。

Here's my very did-it-in-20-minutes demo

票数 8
EN

Stack Overflow用户

发布于 2008-09-16 14:40:36

窗体本身具有完美的Opacity属性,但我不认为大多数单独的控件都具有该属性。你得自己画。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72994

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档