0

I have a Picturebox contain image (sketchImage mode) and I want to make a transparent Label (contain number) in the center of picturebox

So to make the Label transparent i use Parent like this ( in form load event ) :

Label7.Parent = PictureBox2
Label7.BackColor = System.Drawing.Color.Transparent

but now i have problem ! when i start the app the label cituate in the bottom of picture box ? how to fix that !!

Dr.andr
  • 7
  • 3
  • 2
    When you set a new Parent, the coordinates of the child Control are now relative to the parent container. So, if the child Control `.Location = (0, 0)`, it will be moved from the upper/left corner of the previous parent to the upper/left corner of the new Parent. If the `Control.Location` is `(100, 100)`, then... – Jimi May 05 '20 at 23:04
  • 1
    What is sketchImage mode? I don't see a mode property for a PictureBox in WinForms. – Mary May 05 '20 at 23:58
  • @Mary Sounds `StretchImage` –  May 06 '20 at 00:56
  • 1
    It's very bad that you have controls named `Label7` and `PictureBox2`. Get in the habit now of ALWAYS providing meaningful names for things. No one reading that code without prior knowledge would have any idea what those controls are for, including yourself if you leave this project for a while and come back to it later. – jmcilhinney May 06 '20 at 01:11
  • @JQSOFT No StretchImage either. There is `BackgroundImageLayout.Stretch` – Mary May 06 '20 at 01:21
  • @Mary [PictureBox.SizeMode](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.picturebox.sizemode?view=netcore-3.1) Sleepy? :)) –  May 06 '20 at 01:27
  • 1
    @JQSOFT Yes! Played 4 hours of bridge online with friends. I see it now, thanks. – Mary May 06 '20 at 01:29

1 Answers1

1

What I would suggest is that you place the Label exactly where you want it to be in the designer, then translate the Location when you change the Parent, i.e.

Dim labelLocation = myLabel.PointToScreen(Point.Empty)

myLabel.Parent = myPictureBox
myLabel.Location = myPictureBox.PointToClient(labelLocation)

When you add the Label in the designer, its Parent will be the form. The first line above gets the screen coordinates of the Label on the form. The second line moves the Label from the form to the PictureBox, which will move the Label to the same point relative to the top-left of the PictureBox as it was to the top-left of the form. The last line will move the Label back where it was, by translating those screen coordinates to client coordinates relative to the PictureBox.

Here's an extension method you can use to do this for any control:

Imports System.Runtime.CompilerServices

Public Module ControlExtensions

    <Extension>
    Public Sub ChangeParentMaintainingAbsoluteLocation(source As Control, newParent As Control)
        Dim absoluteLocation = source.PointToScreen(Point.Empty)

        source.Parent = newParent
        source.Location = newParent.PointToClient(absoluteLocation)
    End Sub

End Module

Once that's added, either directly to your project or via reference and import, you can simply call that method on the control you want to move. In your case, that would be:

Label7.ChangeParentMaintainingAbsoluteLocation(PictureBox2)

EDIT:

That said, if you specifically want a child control in the centre of its parent:

Dim parentSize = parent.ClientSize

child.Location = New Point((parentSize.Width - child.Width) \ 2,
                           (parentSize.Height - child.Height) \ 2)

The ClientSize is used because some controls - most particularly forms - have borders and those borders may also be asymmetrical. A PictureBox is one control that may have a border, making the client size less than the overall size. Forms will generally have a border and the top is thicker than the bottom, so using ClientSize is even more important.

jmcilhinney
  • 50,448
  • 5
  • 26
  • 46
  • 2
    As a note, you don't need to know the *old Parent*, you can use `source` to get Screen coordinates and translated them to `newParent`, as: `source.Location = newParent.PointToClient(source.PointToScreen(Point.Empty))`. You may need `source.BringToFont()`, though. – Jimi May 06 '20 at 06:31
  • 1
    @Jimi, fair points. I have updated the code to use the source control for location rather than the old parent. – jmcilhinney May 06 '20 at 07:24