Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
642 views
in Technique[技术] by (71.8m points)

winforms - .NET Windows Forms Transparent Control

I want to simulate a 'Web 2.0' Lightbox style UI technique in a Windows Forms application. That is, to draw attention to some foreground control by 'dimming' all other content in the client area of a window.

The obvious solution is to create a control that is simply a partially transparent rectangle that can be docked to the client area of a window and brought to the front of the Z-Order. It needs to act like a dirty pain of glass through which the other controls can still be seen (and therefore continue to paint themselves). Is this possible?

I've had a good hunt round and tried a few techniques myself but thus far have been unsuccessful. If it is not possible, what would be another way to do it?

See: http://www.useit.com/alertbox/application-design.html (under the Lightbox section for a screenshot to illustrate what I mean.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Can you do this in .NET/C#?

Yes you certainly can but it takes a little bit of effort. I would recommend the following approach. Create a top level Form that has no border or titlebar area and then give make sure it draws no client area background by setting the TransparencyKey and BackColor to the same value. So you now have a window that draws nothing...

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;
    }
}

Create and position this DarkenArea window over the client area of your form. Then you need to be able to show the window without it taking the focus and so you will need to platform invoke in the following way to show without it becoming active...

public void ShowWithoutActivate()
{
    // Show the window without activating it (i.e. do not take focus)
    PlatformInvoke.ShowWindow(this.Handle, (short)SW_SHOWNOACTIVATE);
}

You need to make it actually draw something but exclude drawing in the area of the control you want to remain highlighted. So override the OnPaint handler and draw in black/blue or whatever you want but excluding the area you want to remain bright...

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    // Do your painting here be exclude the area you want to be brighter
}

Last you need to override the WndProc to prevent the mouse interacting with the window if the user tries something crazy like clicking on the darkened area. Something like this...

protected override void WndProc(ref Message m)
{
    if (m.Msg == (int)WM_NCHITTEST)
        m.Result = (IntPtr)HTTRANSPARENT;
    else
        base.WndProc(ref m);
}

That should be enough to get the desired effect. When you are ready to reverse the effect you dispose of the DarkenArea instance and carry on.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...