2

I create a program in this can add label and picture box.

All control must is children of a panel.

I use code like this:

panel2.Controls.Add(picturebox1);
panel2.Controls.Add(label1);

Yup, the problem is I want label over picture box.

I was set with code:

label1.Parent = pictureBox1;
label1.BackColor = Color.Transparent;

Update:

Because control only creates when I want to create by button_event. Like, create picture box, create label text. This is not was created before I want to use them.

My code to create this control:

public PictureBox ctrl = new PictureBox();

public void btnAddLogo_Click(object sender, EventArgs e)
{
    Random rnd = new Random();
    int randNumber = rnd.Next(1, 1000);
    String picName = "Pic_" + randNumber;
    ctrl.Location = new Point(200, 170);
    ctrl.Size = new System.Drawing.Size(100, 60);
    ctrl.Name = picName;
    ctrl.BackgroundImageLayout = ImageLayout.Zoom;
    ctrl.Font = new System.Drawing.Font("NativePrinterFontA", 10F, System.Drawing.FontStyle.Regular,
        System.Drawing.GraphicsUnit.Point, ((byte) (0)));
    ctrl.BackColor = Color.Chocolate;
    panel2.Controls.Add(ctrl);
}


private Label ctrLabel = new Label();

public void btnAddCharacter_Click(object sender, EventArgs e)
{
    Random rnd = new Random();
    int randNumber = rnd.Next(1, 1000);
    String LableName = "Lbl_" + randNumber;
    ctrLabel.Name = LableName;
    ctrLabel.AutoSize = true;
    ctrLabel.Text = txtIDImg.Text;
    ctrLabel.BackColor = Color.Transparent;
    panel2.Controls.Add(ctrLabel);
}

But result shows like:

Label not over in picture box. It gets panel is a parent. Panel 1 was added image

jap
  • 21
  • 3
  • You also may find this post helpful: [How to make two transparent layer with c#?](http://stackoverflow.com/a/36102074/3110834) – Reza Aghaei Mar 25 '16 at 02:01

2 Answers2

3

Transparency does work for nested controls; but it is not supported for overlapping controls under winforms. Period.

You could try to workaround by using two labels, one nested in the panel under the pb, the other in the pb.

Here is an example:

enter image description here

    Label l1 = new Label() { Text = "Hello World", BackColor = Color.Transparent };
    Label l2 = new Label() { Text = "Hello World", BackColor = Color.Transparent };
    l1.Parent = scrollPanel;
    l2.Parent = picBox;
    Point pt  = new Point(picBox.Right - 30, 30);
    l1.Location = pt;
    pt.Offset(-picBox.Left, -picBox.Top);
    l2.Location = pt;

The above code could also be put into a reusable function:

Label overlayLabel(Label source, Control target)
{
    Label old = source.Tag as Label;
    if (old != null && old.Parent == target) target.Controls.Remove(old);
    Label lbl = new Label();
    // copy all necessary properties here:
    lbl.Text = source.Text;
    lbl.Font = source.Font;
    lbl.AutoSize = source.AutoSize;
    lbl.Size = source.Size;
    lbl.Anchor = source.Anchor;  // may work or not!
    lbl.BackColor= source.BackColor;
    lbl.ForeColor = source.ForeColor;
    // etc..
    Point pt = source.Location;
    pt.Offset(-target.Left , -target.Top);
    lbl.Location = pt;
    lbl.Parent = target;
    source.Tag = lbl;
    return lbl;
}

In your code you would call it maybe like this; you can store the returned reference:

 panel2.Controls.Add(ctrLabel);
 Label ctrLabelOverlay = overlayLabel(ctrLabel, ctrl );

..or discard it, as it takes care of cleaning up the previous overlay, which is stored in the Tag of the Label..:

 panel2.Controls.Add(ctrLabel);
 overlayLabel(ctrLabel, ctrl );

But the most direct way is to draw those things, ie the text and the image yourself. Two or so lines in the panel's Paint event..:

if (img != null)
{
   Rectangle rect = new Rectangle(pt1, img.Size);
   e.Graphics.DrawImage(img, rect);
   e.Graphics.DrawString("Hello World", Font, Brushes.Black, pt2);
}

All you need is to calculate the two locations pt1 and pt2. If your Picturbox is stretching or zooming you will also need to write the source rectangle into the DrawImage overload that can zoom/stretch the image.

To enforce the display call panel2.Invalidatewhenever something changes..

Simpler and much more powerful, unless you need special abilities of Label or PictureBox..

Note all theres things are happening in code, so don't expect things to show up in the designer. Writing code so that it does show in the VS designer is not all that easy..

TaW
  • 53,122
  • 8
  • 69
  • 111
  • Yes, drawing string directly in Paint event is the best solution. – Anton Kedrov Jan 30 '16 at 22:07
  • Which part? If it is the first: Make sure the stacking order is right. Maybe insert a `picBox.BringToFront()`. And obviously use your control names! If it is the paint version: Put the code in the Paint event of the panel and [hook it up](http://stackoverflow.com/questions/33275763/copy-datagridview-values-to-textbox/33276161?s=1|0.3898#33276161)! - Do describe 'didn't work'! As you can see from the screenshot it works fine here.. – TaW Jan 30 '16 at 22:56
  • Neither. If you want to test version 2 there really is __neither the label nor the picurebox__ necessary anymore. If had left in a reference but it should refer to the size of the image you want to draw. Since everything is supposed to show on the panel2 you should create and code it's Paint event! – TaW Jan 31 '16 at 17:21
  • Label and PictureBox only active when I click the button to create them. So, if I put this code into `panel_Paint` - the panel is load first. It will return exception `Object reference not set to an instance of an object`. I tested this code and it shows like this. I think your answer is true. But it has any problem make my program was not working. It show like this: http://i.imgur.com/TrrePbw.gif – jap Jan 31 '16 at 19:20
  • 1: Yes, if the image is not set you can't draw it; so simply put the drawing code in an if clause: `if (ctrl.Image != null) {..}` - 2) No, the function can receive the picturebox just fine as it is derived from control. __Which line brings the error?__ (You could change the function to receive a pbox of course but I like to keeps things flexible..) – TaW Jan 31 '16 at 19:53
  • I understand your Control parameter is flexible. `Label ctrLabelOverlay = overlayLabel(ctrLabel, ctrl);` this line throw error. Error at class `overlayLabel`. `Cannot implicitly convert type 'System.Windows.Forms.Control' to 'System.Windows.Forms.Label'. An explicit conversion exist(are you missing cast)` – jap Jan 31 '16 at 20:21
  • You are right, sorry, my bad, I made a typo when editing the answer. The correct return value should be `Label`. – TaW Jan 31 '16 at 20:26
  • Thanks @TaW, but my result receive is: http://i.imgur.com/kMC7ZhH.png The result has 3 things. Object 1 have background color orange I think this create by overlayLabel() class. I was put `ctrLabel.BringToFront` in event `MouseMove` to active `Label` over PictureBox. – jap Jan 31 '16 at 20:57
  • 1) Whoops, yes The overlay label function missed cloning the background color. fixed. 2) do __not__ bring the ctrLabel to the front! it should be under the picturebox! 3) I don't know why the overlayed label is positioned wrong; the code works fine here, no matter where I place pbox or label.. – TaW Jan 31 '16 at 21:04
  • If the label is over the picturebox (because it was created later) then you must call bringtofront on the pbox: `ctrl.BringToFront()` - BTW: After trying stuff repeatedly it often helps to start a test application with just the things needed to test the problem. Often there are remnantts from failed attempts still lurking around and mess up the new good code. This way you can be sure to be on the right track.. – TaW Jan 31 '16 at 22:09
  • I was thinking a method. This is when drag logo to 1 position, I will save this(background panel + logo). And continues save logo. You think this method is ok @TaW? – jap Feb 01 '16 at 03:37
  • I don't understand. Are you talking about designer or runtime? saving the backgroud yourself is a big hassle. not necessary imo. when you drag label or picturebox during runtime you need to adapt the location of the overlay label, of course.. – TaW Feb 01 '16 at 06:53
0

Windows forms does not support true transparency, Go through this. http://www.broculos.net/2008/03/how-to-use-transparent-images-and.html#.Vq0q2jZuncc