I’ve been trying to display an image which has a transparent border as the background to a control.
Unfortunately, the transparent area creates a hole in the parent form as follows:

In the above image, the form has a red background which I’d hoped to see behind my control in the transparent areas.
The code I used is as follows:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
if (this.Image != null)
{
Graphics g = Graphics.FromImage(this.Image);
ImageAttributes attr = new ImageAttributes();
//set the transparency based on the top left pixel
attr.SetColorKey((this.Image as Bitmap).GetPixel(0, 0), (this.Image as Bitmap).GetPixel(0, 0));
//draw the image using the image attributes.
Rectangle dstRect = new Rectangle(0, 0, this.Image.Width, this.Image.Height);
e.Graphics.DrawImage(this.Image, dstRect, 0, 0, this.Image.Width, this.Image.Height,
GraphicsUnit.Pixel, attr);
}
else
{
base.OnPaint(e);
}
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
{
//base.OnPaintBackground(e);
}
This class is inherited from a PictureBox because I needed a control which implements OnMouseMove and OnMouseUp Events.
I’ve been researching most of the day without success testing out different ideas but unfortunately most only work on the full framework and not .Net CF.
Any ideas would be much appreciated.
Ah the joys of CF transparency. I could go on and on about it (and have in my blog and the Project Resistance code I did ages ago).
The gist is this. The child control has to paint it’s areas, but first it has to call back up to it’s parent (the Form in your case) and tell it to redraw it’s background image everywhere except in the child’s clipping region and then draw itself on top of that. If that sounds a bit confusing it’s because it is.
For example, if you look at Project Resistance, a View (which is just a Control) draws a resistor and bands. It lies in a Form that has an image background, and that background needs to “show through” the transparent areas of the resistor:
So in the drawing code of the resistor it does this:
Which is simple enough. The key is that it calls to it’s base OnPaint, which does this:
You can see it’s calling
PaintBackgroundof the containing Form (it’s Parent.Parent in this case becuse the Control is actually in a container called a Workspace – you wouldn’t need to walk up twice in your case). That draws in the background image in the area you’re currently seeing as the “hole”