Label disappears when an Image is assigned to a PictureBox under it

technonaut

I've been through quite a number of posts about adding a Label over a PictureBox, and none of the ones I've seen explain why my label disappears when over a PictureBox.
I created a completely new Label from scratch with the same problem, to rule out that perhaps I inadvertently changed some property without realizing it.

When the Form first loads, the PictureBox has no initial image set.
At this time, the Label is visible, but it's Paint event isn't called.

When an Imaged is assigned to the PictureBox, through a Button click, the Label is no longer visible and the Paint event still isn't called.

However, Paint events for another Label, outside of the PictureBox, are called.

In the designer I see this:

Me.tabDesign.Controls.Add(Me.lblTitleTest)

Thus, following this post and this one, I do this:

Me.lblTitleTest.Location = Me.picMainImage.PointToClient(Me.tabDesign.PointToScreen(lblTitleTest.Location))
Me.lblTitleTest.Parent = Me.picMainImage

But it doesn't have any effect.

Next, I tried using the Paint event (below), but the event is only called for Labels outside of the PictureBox.
The Paint event is not called if the Label is positioned over top of the PictureBox:

Private Sub DrawTestTitleText(sender As Object, e As PaintEventArgs) Handles lblTitleTest.Paint
    MsgBox("Drawing new test title")
    TextRenderer.DrawText(e.Graphics, "Test Title", lblTitleTest.Font, New Point(10, 10), Color.Black)
End Sub

If I use this same code with a different Label, not over the PictureBox, the draw event fires as expected.

As a test, I tried to assign an Image from the Project's Resources to the PictureBox. That didn't help: the Label wasn't ever visible at all and its Paint event never triggered.

There must be some subtle nuance here there I'm missing.

I'm targeting .NET Framework 4.6.1.

Jimi

Relocate a Control to a different Parent container maintaining the relative position:

Assume, as in the graphic sample, that the PictureBox.Location is (10, 100). In the Form Designer, a Label is positioned over the PictureBox, its Location is (20, 110).
Its position, relative to the PictureBox.ClientRectangle, is then (10, 10) => (20-10, 110-100)).

Of course, as shown, the Label's background color is inherited from its Parent, the Form (transparency of Controls is virtual, the Parent's background is used as the background of child Control that have a transparent BackColor).

► The PictureBox control is not a ContainerControl or a ScrollableControl (it doesn't implement IContainerControl; i.e., doesn't have the WS_EX_CONTROLPARENT style set), so it doesn't host a Control when you place one over its surface at design-time.

At run-time, you can set a Control's Parent property to a PictureBox reference, to create a new Parent-Child relation between these two Controls.
When you do, some properties related to a Control's layout need to be considered; in this case the Location property.
Setting the Parent doesn't change the child Control's Location value, which is now relative to the new Parent.

► The Label.Location is still (20, 110), but now this position is related to the PictureBox.ClientRectangle, not the Form's. As a consequence, you have to relocate it, if you want it to keep its relative position.

  1. You can subtract the new Parent's Location from the child Control's Location:

    [Label].Parent = [PictureBox]
    [Label].Location = Point.Subtract([Label].Location, New Size([PictureBox].Left, [PictureBox].Top))
    
  2. Or transform the Labels's client coordinates in Screen coordinates, then apply the Screen coordinates to the Parent's client coordinates:

    [Label].Location = [PictureBox].PointToClient([Label].PointToScreen(Point.Empty))
    

When the Label is set to a new Parent container, its background is also adapted to the new Parent's background, to preserve the apparent transparency.

In Form.Load (assume the Label is named label1 and the PictureBox pictureBox1):

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    label1.Parent = pictureBox1
    label1.Location = pictureBox1.PointToClient(label1.PointToScreen(Point.Empty))
    ' Or
    ' label1.Location = Point.Subtract(label1.Location, New Size(pictureBox1.Left, pictureBox1.Top))
End Sub
                Design-Time:                               Run-Time:

enter image description here enter image description here

You can do the exact same thing drawing the text directly on the PictureBox surface, in the same position, defining the drawing Rectangle where the Text will be drawn, the same position and size as the Label you previously used.

NOTE:
Here, I'm using the the PictureBox Font property as the Font parameter of TextRenderer.DrawText. The PictureBox hides this property, but it's still available (belongs to the Control class); it's inherited from its Parent, Form or other container. You can of course specify any other Font.

See the TextRenderer's TextFormatFlags, to place the Text in other positions (e.g., Top/Left).
Here, TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter are used to center the text in the middle of the drawing box, defined by drawingRect in the Paint event.

private canvasFlags as TextFormatFlags = TextFormatFlags.HorizontalCenter Or
                       TextFormatFlags.VerticalCenter Or TextFormatFlags.NoPadding
private canvasText as String = "Some Text just for show"

private sub picCanvas_Paint(sender As object, e As PaintEventArgs) Handles pictureBox1.Paint
   Dim pBox = DirectCast(sender, PictureBox)
   Dim drawingRect = new Rectangle(10, 10, pBox.Width - 20, pBox.Font.Height + 4)
   TextRenderer.DrawText(e.Graphics, canvasText, pBox.Font, drawingRect, Color.White, Color.Empty, canvasFlags)
End Sub

At Run-Time, Invalidate() the PictureBox when you want to repaint it to, e.g., replace the Text.
Resulting in:

TextRenderer drawing Text

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

A image disappears under a div

Label under image in UIButton

How do I repaint my picturebox when the picture disappears?

Image disappears when position: absolute

Image disappears when resizing the canvas

Last label on xaxis disappears when resize

How to detect when the image appears in PictureBox

Button image background disappears when on hover

Image disappears when hovering then appears - CSS

when using the arrow keys my image disappears

When I set a width on the image it disappears (fllexbox)

Image that disappears when dragging it to a target on Kivy

The border disappears when opacity is added to the image

How to load picturebox image when the connection to the image's site is not private?

label disappears when i launch app the second time

Why the IBOutlet label disappears when I push back again to the VC?

How to put label under image in navigation bar?

Property value prints but when assigned to label it shows nil

Image from Picturebox to another Picturebox

image disappears when styling class to make a round image

Background image sometimes disappears when loading a png image over it

Cannot get image to display in picturebox when trying to load if from the DB

Picturebox throws "Argument is not valid" when assigning a MetaFile to an image

error when i'm trying to delete an image used in a picturebox

What are some reasons that a PictureBox or Label might not display their respective image or text in the situation described below?

variable assigned when it is assigned

CMFCToolbar image disappears through remote desktop or when connected to projector

When I update the QPixmap of a QGraphicsPixmapItem, the image disappears from the scene

image disappears when container becomes flex container gatsby