0

first of all, I'm new to C# Forms (and also new to StackOverflow). I want to have a small launcher window. I disabled the title bar, so the Main Form is supposed to just be there and hold the UI elements. I added a slightly smaller PictureBox that I want to be the "real" background so it will create a neat border between the main form and the background image. So far so good.

The issue is now that all UI elements that use transparent background and are placed on top of the PictureBox will now display the background of the main form instead of the PictureBox and it looks terrible.

I am confused. I tried sending the main form to back, I tried to add the PictureBox manually by code.. but it's all the same result. The PictureBox seems to be in front of the main form, but transparent UI elements will use the BackColor of the main form instead of the Background Image of the PictureBox that's there.

What am I missing? Any help appreciated. :)

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
alex
  • 21
  • 1
  • Does this answer your question? [C# Picturebox transparent background doesn't seem to work](https://stackoverflow.com/questions/5522337/c-sharp-picturebox-transparent-background-doesnt-seem-to-work) – Ian Kemp Jan 15 '21 at 16:39
  • Yes and no.. it looks like it's the same problem. I took from that that I need custom controls. I created a new Controls by inheriting from PictureBox, but right now it's not showing at all. I'm trying to get it working. – alex Jan 15 '21 at 18:07
  • [Multi Layer Transparent PictureBox and TransparentLabel](https://stackoverflow.com/a/36102074/3110834) – Reza Aghaei Jan 19 '21 at 09:09
  • @RezaAghaei None of them is a container nor transparent (yet) to the mouse events. Both are required here. I'd recommend them for something like [this](https://stackoverflow.com/a/37473192/14171304) though. – dr.null Jan 20 '21 at 19:16

1 Answers1

0

I added a slightly smaller PictureBox that I want to be the "real" background so it will create a neat border between the main form and the background image.

That background PictureBox is causing this. The smaller picture boxes with the transparent back color need to be placed directly into a container with a background image and nothing in between. For example, you could remove the background picture box and override the Form's OnPaint method to draw the background image and leave some margins:

using System;
using System.Drawing;
using System.Windows.Forms;

public partial class LauncherForm : Form
{
    public LauncherForm() : base()
    {
        DoubleBuffered = true;
        ResizeRedraw = true;
        BackColor = Color.Black;
        Padding = new Padding(20);
        ControlBox = false;
        FormBorderStyle = FormBorderStyle.None;
    }

    private Image bgImage;
    public new Image BackgroundImage
    {
        get => bgImage;
        set { bgImage = value; Invalidate(); }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        var g = e.Graphics;
        var r = new Rectangle(Padding.Left, Padding.Top,
            Width - Padding.Left - Padding.Right,
            Height - Padding.Top - Padding.Bottom);

        g.Clear(BackColor);

        if (BackgroundImage != null)
            g.DrawImage(BackgroundImage, r);

        g.DrawRectangle(Pens.DimGray, r);
    }
}

Another option is to do the same but with a Panel control to host the other picture boxes:

  • Select your project.
  • Right click and select Add -> Class...
  • In the add dialog, rename the class to LauncherPanel.cs and hit the Add button.
  • Replace the class block only (keep the namespace) in the new class with the code below.
  • Save and rebuild.
  • Open the designer, check the top of the ToolBox window, you'll find the new control LauncherPanel under the components of your project.
  • Drop an instance into the designer.
  • Select the control and press F4 key to activate the Properties window. Set the Image property and optionally the BorderColor and BorderWidth properties.
  • Add the other picture boxes into the launcherPanel1 or whatever you name it.
using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;

// Within the namespace of your project..
[DesignerCategory("")]
public class LauncherPanel : Panel
{
    public LauncherPanel() : base()
    {
        DoubleBuffered = true;
        ResizeRedraw = true;
        BackColor = Color.Black;            
    }

    private Image bgImage;
    public Image Image
    {
        get => bgImage;
        set { bgImage = value; Invalidate(); }
    }

    private Color borderColor = Color.DimGray;
    [DefaultValue(typeof(Color), "DimGray")]
    public Color BorderColor
    {
        get => borderColor;
        set { borderColor = value; Invalidate(); }
    }

    private int borderWidth = 1;
    [DefaultValue(1)]
    public int BorderWidth
    {
        get => borderWidth;
        set { borderWidth = value; Invalidate(); }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        var g = e.Graphics;
        var r = ClientRectangle;
        r.Width--;
        r.Height--;

        g.Clear(BackColor);

        if (Image != null)
            g.DrawImage(Image, r);

        using (var pn = new Pen(borderColor, borderWidth))
            g.DrawRectangle(pn, r);
    }
}

Choosing the Panel option, you will get something like this at design time:

SOQ65739945A

And like this at runtime:

SOQ65739945B

Make sure you have transparent PNG images for the picture boxes in the Panel.

dr.null
  • 4,032
  • 3
  • 9
  • 12
  • Thank you very much for the detailed answer! This works just as I need it and also taught me a lot about how to approach things. I created a new CustomControls for that, I hope that was the correct way to implement this - seems to work, so it can't be too far off. Where is it best to parent objects? I don't find an option to do that in the Designer window, so currently I do it in the constructor of my main form after InitializeComponents() was called. Is there a better place to do this? Again thank you very much, really appreciated! – alex Jan 16 '21 at 18:04