Introduction
I needed to add transparent buttons to my .NET application, so I searched the web from start to end, and all that came up was more or less confusing information. In the end, I implemented it myself, and decided to share it for everyone's benefit.
Background
I found a number of different scenarios under the same catch-all "transparent buttons" phrase:
- You may want a freeform button, whose only active parts are its foreground pixels - this article does not cover this scenario. In my case, the button still has the good old rectangle shape, although the image displayed may be irregular.
- You may want a text button whose background should be transparent. This turned out to be pretty easy (see the code sample).
- You may want a button with an image, where the background of the image is transparent. This is more tricky, but fairly simple (see code sample).
- You may want to use alpha blending so that the button image dissolves into the background - there is no sample for this in this article.
The samples below (and the sample application in the download) assumes that you:
- have a Windows Form with a
PictureBox
(named PictureBoxWithBear
), with an image assigned to it, - a
Button
with its Text
property set (named TextButton
), - another button where we will not display text, but an image (named
ImageButton
).
(All the sample code goes into the constructor of the form.)
Using the Code
Let's jump right into it!
Problem 1: Add a text button with a transparent background
this.TextButton.Parent = this.PictureBoxWithBear;
this.TextButton.BackColor = Color.Transparent;
Problem 2: Add a button with an image with transparent background
We already know how to set the background of the button to transparent - we use it here. But, we also have to set the background of the image to transparent. Here is how: normally, you would assign an image to the Button.Image
property - but unfortunately, Image
does not support TransparentColor
. But, ImageList
does!
So, this is what we should do:
- Create an image with some special background color (in the sample, this is
Color.Magenta
, 0xff00ff). - Load that image (from file or resource).
- Add it to the button's
ImageList
(not to the Image
!) property. - Set the
TransparentColor
of the ImageList
to the special color you chose.
This will be the result:
And this is the code to do that:
this.ImageListButton.Parent = this.PictureBoxWithBear;
this.ImageListButton.BackColor = Color.Transparent;
this.ImageListButton.FlatAppearance.MouseOverBackColor = Color.Transparent;
Image TheImageStrip = Image.FromFile("ImageStrip32x32.bmp", true);
ImageList TheImageList = new ImageList();
TheImageList.ImageSize = new Size(32, 32);
TheImageList.Images.AddStrip(TheImageStrip);
TheImageList.TransparentColor = Color.Magenta;
this.ImageListButton.ImageList = TheImageList;
this.ImageListButton.ImageIndex = 3;
Transparent Buttons in Compact Framework 2.0
In theory, you should be able to do the same in CF2, but you can't. When you try to set the button's parent, an InvalidArgumentException
is thrown. To work around this problem, you have to draw the button face as if it was transparent: Pick up the content from the background, paint it on top of your button, and then, over that, paint your own image.
The other problem is that you can't specify a transparent color for either the Image
or the ImageList
object. But Graphics.DrawImage
does know about transparency: One of its overloads accepts an ImageAttributes
parameter. Using ImageAttributes
(in theory), you can specify a range of colors that will be displayed transparent. In reality you can only specify a range that contains a single color (the limits of the interval are the same), but never mind, a single color will do for now.
Here is how you do it:
Bitmap MergedImage = new Bitmap(this.Width, this.Height);
Graphics MergedImageGraphics = Graphics.FromImage(MergedImage);
MergedImageGraphics.DrawImage(
ParentImage,
new Rectangle(0, 0, MergedImage.Width, MergedImage.Height),
new Rectangle(this.Left, this.Top, this.Width, this.Height),
GraphicsUnit.Pixel
);
ImageAttributes ia = new ImageAttributes();
ia.SetColorKey(this.TransparentColor, this.TransparentColor);
MergedImageGraphics.DrawImage(
this.ForegroundImage,
new Rectangle(0, 0, MergedImage.Width, MergedImage.Height),
0, 0, ForegroundImage.Width, ForegroundImage.Height,
GraphicsUnit.Pixel, ia);
e.Graphics.DrawImage(MergedImage, 0, 0);