Introduction
Showing a dialog with overlay looks cool on Windows. For this TransparencyKey
is set to a color and color of form is changed to that color and in result form becomes 100% transparent. The problem starts when color of any control on form matches with TransparencyKey
; that part also becomes transparent. This tip will help you to solve this problem.
Background
I was developing an application with transparent forms where I have to
show a picturebox with a little transparency. I have set the
TransparentKey
to color X and when a picture with X color is shown that
part becomes 100% transparent and by clicking that part, the user can click on the window behind the control.
Using the Code
I have used Visual Studio 2010, C# and .NET Framework 4.0 for this demo. There are two forms frmForeground
is transparent form and frmBackground
is a solid form that hides the transparency of image on foreground form.
Now user should show background form instead of foreground. In background forms' load event handler, it will load foreground form. The important point is to register a close event handler of foreground form so that background/owner form is notified about the closing of foreground form. To avoid recursion & stack overflow, this event handler must be unregistered when its notification is called. See frontFormCloseNotify()
.
private void frmBackground_Load(object sender, EventArgs e)
{
frontForm = new frmForeground();
frontForm.StartPosition = FormStartPosition.Manual;
frontForm.FormClosed += new FormClosedEventHandler(frontFormCloseNotify);
frontForm.Show(this);
frontForm.BringToFront();
}
public void ChangePosition(Point position)
{
System.Diagnostics.Trace.WriteLine("frmBackground Change Position: " + position.ToString());
this.StartPosition = FormStartPosition.Manual;
this.Location = position;
}
private void frontFormCloseNotify(object sender, FormClosedEventArgs e)
{
System.Diagnostics.Trace.WriteLine("frontFormCloseNotify in frmBackground ");
if (sender is frmForeground)
{
frontForm.FormClosed -= new FormClosedEventHandler(frontFormCloseNotify);
this.Close();
}
}
Form foreground should set position of its owner when it is loaded and should also set owner's position when it is moved. When this form is closed, only this.Close()
has to be called and owner/background form will be notified because it has also registered a handler for Close
event. Hiding parent form is different than closing.
private void frmForeground_Load(object sender, EventArgs e)
{
frmBackground owner = this.Owner as frmBackground;
if (owner == null)
return;
owner.Location = this.PointToScreen(this.pictureBox1.Location);
owner.Size = new Size(this.pictureBox1.Size.Width, this.pictureBox1.Size.Height);
}
private void frmForeground_Move(object sender, EventArgs e)
{
frmBackground owner = this.Owner as frmBackground;
if (owner == null)
return;
owner.ChangePosition(this.PointToScreen(this.pictureBox1.Location));
}
private void buttonClose_Click(object sender, EventArgs e)
{
this.Close();
}
private void buttonHide_Click(object sender, EventArgs e)
{
this.Hide();
if (this.Owner != null)
this.Owner.Hide();
}
History