Introduction
The article discusses one way to create non-rectangular MDI Parent forms: Transparency Key.
Background
This article is based on some questions I've seen people asking: when we set the IsMdiContaner
property of a Form
to true
, the background color cannot be changed! The form can't be transparent and... So, here we go.
Using the Code
So, how is this done? It is very simple.
First of all, don't set the IsMdiContaner
property of the Form
to true
! Just create a project, and do this in the Form_Load
event handler:
this.TransparencyKey = Color.FromArgb(255, 220, 33, 55);
MdiClient Client = new MdiClient();
this.Controls.Add(Client);
Form Child = new Form();
Child.Size = new Size(100, 100);
Child.FormBorderStyle = FormBorderStyle.FixedDialog;
Child.StartPosition = FormStartPosition.CenterParent;
Child.MaximizeBox = false;
Child.MinimizeBox = false;
Child.MdiParent = this;
this.pictureBox1.Controls.Add(Child);
Child.Show();
Well, what's that?
Let's take a line to line approach. First, we have an image (for example, a PNG image which supports transparent color, just like Image.png in the source included) where the unwanted areas of the form are marked with a specific color (here, I used Adobe Photoshop, and the color has the RGB equivalent: R = 220, G = 33, B = 55).
So, we load it to a PictureBox
, and put it on the Form
, setting the PictureBox
's Dock
property to Fill
. Alright. Now, it's time to reshape the form.
The concept is simple: by setting the TransparencyKey
property of any .NET Framework Form
object, it will change any TransparencyKey
colored pixel existing with a TransparentColor
pixel. So, whatever is behind that pixel will be visible, just like through a glass.
So, in the first line, we set the property as needed:
this.TransparencyKey = Color.FromArgb(255, 220, 33, 55);
(for transparenting the MdiClient
itself, TransparencyKey
must be set to this instead of above :
this.TransparencyKey = Color.FromArgb(255, 171, 171, 171);
)
So far, we have reshaped the form. But always remember, only the form's look will change this way, not its region! So, its Height
, Width
, etc., are the same values as before.
Now, we create a MdiClient
object and place it on the form. When you set the IsMdiContainer
property of any form to true
, by default, an MdiClient
object will be added to the form, and it takes control of its paint and background paint events.
(There is a very good article about MdiClient
by Jacob Slusser, for further readings about this object: Getting a "Handle" on the MDI Client. I would suggest that you read it!)
Here, we do this by ourselves:
MdiClient Client = new MdiClient();
this.Controls.Add(Client);
Hopefully, you've got the trick by now! If not, it doesn't matter: I'll explain.
It is the order of adding objects to the form's 'Controls
' collection. Here, we first added the PictureBox
to the collection, and then MdiClient
, but, by setting the IsMdiContainer
property, the first object in the Controls
collection will be MdiClient
. So, the paint event will not do transparency.
Now, create the child form and set its MdiParent
property to the current form.
Form Child = new Form();
Child.Size = new Size(100, 100);
Child.FormBorderStyle = FormBorderStyle.FixedDialog;
Child.StartPosition = FormStartPosition.CenterParent;
Child.MaximizeBox = false;
Child.MinimizeBox = false;
Child.MdiParent = this;
But, doing this is not just enough. If you call the Show()
method right now, you'll not see the child form! Why is that?!
Remember the trick? The 'Controls
' collection! Your child form will be under the PictureBox
. I've solved this by adding the child form to the PictureBox
's Controls
collection (however, there are other ways to do this).
this.pictureBox1.Controls.Add(Child);
Now, by calling Show()
, you'll see your child form:
Child.Show();
Done!
Just remember, the parent form's area is still the same as before making it transparent! So, the child form can be moved to this area, even to transparent areas. This has its own uses, so I'll let it be this way.
TODO (coming soon!): Restrict the child form from moving outside the non-transparent areas! ;)
Hope this helps someone.
History
- 27th January, 2010: Initial post
- 27th January, 2010: Article updated