Winforms semi-transparent PNG over semi-transparent PNG

pngtransparencyuser interfacewinforms

I think I must be missing something obvious, but I'm unable to find this after several hours of searching. Is there no way to use a PictureBox or other control to contain an image with partial transparent/alpha-blended pixels, and place that over another image and have the blending be based on the image under it?

For example, this produces the results I want:

  1. Place a panel on a form.
  2. Add an OnPaint handler.
  3. In the OnPaint handler draw 1 PNG, then draw another PNG over it, using Graphics.DrawImage for both.

This does not:

  1. Place a PictureBox on a form and set it to a PNG.

  2. Place another PictureBox on the form and set it to a PNG.

  3. Place the 2nd picture box over the first.

…even if the 2nd picture box is just empty and has a background color of Transparent, it still covers the picture below it.

I've read this stems from all winform controls being windows, so by nature they aren't transparent.

…but even the 15 year old platform I'm migrating from, Borland's VCL, had several windowless controls, so it's hard to imaging winforms doesn't at least have some easy solution?

My first example above is one answer, true, but that adds a lot of work when you can only use one big panel and draw all of your "controls" inside of it. Much nicer if you can have separate controls with separate mouse events/etc. Even if not an image control, and a control I have to draw myself, that would be fine, as long as I can just put one image in each control. In VCL they called this a "paint box", just a rectangle area you could place on a form and draw whatever you want on it. Has it's own mouse events, Bounds, etc. If you don't draw anything in it, it is like it's not even there (100% transparent) other than the fact it still gets mouse events, so can be used as a "hot spot" or "target" as well.

Best Answer

The PictureBox control supports transparency well, just set its BackColor property to Transparent. Which will make the pixels of its Parent visible as the background.

The rub is that the designer won't let you make the 2nd picture box a child of the 1st one. All you need is a wee bit of code in the constructor to re-parent it. And give it a new Location since that is relative from the parent. Like this:

    public Form1() {
        InitializeComponent();
        pictureBox1.Controls.Add(pictureBox2);
        pictureBox2.Location = new Point(0, 0);
        pictureBox2.BackColor = Color.Transparent;
    }

Don't hesitate to use OnPaint() btw.

Related Topic