Windows Develop Bookmark and Share   
 index > Windows Forms General > Layering Opaque Panels & BringToFront() [code included] - Any Help Please?
 

Layering Opaque Panels & BringToFront() [code included] - Any Help Please?

I know the title isn't very descriptive, but that is because I'm not exactly sure what to ask here.

In my application when the user clicks a button I want to bring up an opaque panel that covers all of the controls and then prompt the user for input. I've successfully created the opaque panel, however when I use BringToFront() it does in fact bring it to the front, but some elements appear not to be covered. See the link for a screenshot.



In my example it appears that the Labels of my custom UserControl don't get their backgrounds colored. Am I forgetting something or is this happening by design of the UserControl?

Code Snippet

// TransPanel.cs

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;


namespace WindowsApplication1
{
/// <summary>
/// Summary description for TransPanel.
/// </summary>
public class TransPanel : UserControl
{

public TransPanel ()
{
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.EnableNotifyMessage, true);
}

protected override CreateParams CreateParams
{
get
{
CreateParams cp=base.CreateParams;
cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}

protected override void OnPaintBackground(PaintEventArgs pevent)
{
//do not allow the background to be painted
}

protected override void OnPaint(PaintEventArgs e)
{
Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);
SolidBrush b = new SolidBrush(Color.FromArgb(205, Color.Black));
e.Graphics.FillRectangle(b, rect);

b.Dispose();
}
}
}


Code Snippet

// UserControl1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
public partial class UserControl1 : UserControl
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Component Designer generated code

private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.BackColor = System.Drawing.Color.Transparent;
this.label1.Location = new System.Drawing.Point(25, 34);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(35, 13);
this.label1.TabIndex = 0;
this.label1.Text = "label1";
//
// UserControl1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Highlight;
this.Controls.Add(this.label1);
this.Name = "UserControl1";
this.ResumeLayout(false);
this.PerformLayout();

}

#endregion

private System.Windows.Forms.Label label1;


public UserControl1()
{
InitializeComponent();
label1.SendToBack();
}
}
}


Code Snippet

// Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.userControl11 = new WindowsApplication1.UserControl1();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.BackColor = System.Drawing.Color.Transparent;
this.label1.Location = new System.Drawing.Point(13, 13);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(35, 13);
this.label1.TabIndex = 0;
this.label1.Text = "label1";
//
// label2
//
this.label2.AutoSize = true;
this.label2.BackColor = System.Drawing.Color.Transparent;
this.label2.Location = new System.Drawing.Point(13, 43);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(35, 13);
this.label2.TabIndex = 1;
this.label2.Text = "label2";
//
// userControl11
//
this.userControl11.Location = new System.Drawing.Point(304, 158);
this.userControl11.Name = "userControl11";
this.userControl11.Size = new System.Drawing.Size(150, 150);
this.userControl11.TabIndex = 3;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(629, 482);
this.Controls.Add(this.userControl11);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();

}

#endregion

private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private UserControl1 userControl11;


public Form1()
{
InitializeComponent();
TransPanel tp = new TransPanel();
this.Controls.Add(tp);
tp.Location = new Point(2, 2);
tp.Size = new Size(this.Width, this.Height);
tp.BringToFront();
userControl11.Invalidate();
}
}
}


Any help on figuring out how to gray out the label in the blue box would be awesome. Thank you!
aur0ra7  Thursday, September 06, 2007 6:03 PM
Hmm, looks familiar. Transparency in Windows is a parlor trick and falls flat on its face in this case. The label control clearly is painted last, after TransPanel, thus destroying the transparency effect. I'd assume this has something to do with the fact that it is located on a UserControl and Windows fails to detect the proper Z-order.

Another way to do this is to overlay the client area of your form with another form whose Opacity value is set to a value less than one. Transparency in this case is done by the video adapter hardware and is both very fast and accurate. Add a new form to your project, named FMask and paste this code:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsApplication1 {
public partial class FMask : Form {
public FMask(Form parent) {
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = Color.Black;
this.Opacity = 0.50;
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.Manual;
this.Size = parent.ClientSize;
this.Location = parent.PointToScreen(Point.Empty);
parent.Move += AdjustPosition;
parent.SizeChanged += AdjustPosition;
}
private void AdjustPosition(object sender, EventArgs e) {
Form parent = sender as Form;
this.Location = parent.PointToScreen(Point.Empty);
this.ClientSize = parent.ClientSize;
}
}
}

Then in your original Form1, remove the TransPanel code and add a Load event:
private FMask overlay;
private void Form1_Load(object sender, EventArgs e) {
overlay = new FMask(this);
overlay.Show(this);
}

To remove the overlay, just call overlay.Close() and set overlay = null.
nobugz  Friday, September 07, 2007 7:15 PM
Hmm, looks familiar. Transparency in Windows is a parlor trick and falls flat on its face in this case. The label control clearly is painted last, after TransPanel, thus destroying the transparency effect. I'd assume this has something to do with the fact that it is located on a UserControl and Windows fails to detect the proper Z-order.

Another way to do this is to overlay the client area of your form with another form whose Opacity value is set to a value less than one. Transparency in this case is done by the video adapter hardware and is both very fast and accurate. Add a new form to your project, named FMask and paste this code:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsApplication1 {
public partial class FMask : Form {
public FMask(Form parent) {
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = Color.Black;
this.Opacity = 0.50;
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.Manual;
this.Size = parent.ClientSize;
this.Location = parent.PointToScreen(Point.Empty);
parent.Move += AdjustPosition;
parent.SizeChanged += AdjustPosition;
}
private void AdjustPosition(object sender, EventArgs e) {
Form parent = sender as Form;
this.Location = parent.PointToScreen(Point.Empty);
this.ClientSize = parent.ClientSize;
}
}
}

Then in your original Form1, remove the TransPanel code and add a Load event:
private FMask overlay;
private void Form1_Load(object sender, EventArgs e) {
overlay = new FMask(this);
overlay.Show(this);
}

To remove the overlay, just call overlay.Close() and set overlay = null.
nobugz  Friday, September 07, 2007 7:15 PM
Thanks for the reply. I've tried your suggestion in the past but was hoping I could do it by drawing my own panels Wink I've had some screwey instances where the overlay got stuck behind the parent. But I suppose I'll just have to be more careful about that. Thanks for your suggestion.
aur0ra7  Monday, September 10, 2007 11:18 AM
It will always stay on top, as long as you use the Show(owner) overload to show it.
nobugz  Monday, September 10, 2007 11:45 AM

You can use google to search for other answers

Custom Search

More Threads

• Multi language help please
• posted this once and no replies... PLEASE HELP!
• Problem with Open/execute file.
• populate DropDownItems and assign one Click function to all
• courier font missing
• Small accounting application Big headache (SAAB-H)
• How to create shortcut through command prompt?
• Passing Over the DataGridView Cells While Tabbing..?
• Movement between forms
• Using a secondary key with Linq