Question Transparent background over a picturebox

J. Scott Elblein

Well-known member
Joined
Dec 14, 2006
Messages
166
Location
Chicago
Programming Experience
10+
I have a picturebox with a pic in it, and I have a label on top of the picture.

I want the background of the the label to be transparent, so I set it's background prop to transparent and it's parent to the picturebox. I do this on form load, but for some reason the label entirely disappears once the form loads?
 
Why don't you just draw the text over the image in Paint event of the picturebox?
VB.NET:
Using b As New SolidBrush(Me.ForeColor)
    e.Graphics.DrawString("label text", Me.Font, b, 10, 10)
End Using
 
Great suggestion, I had never played with painting yet. I should of mentioned in my op that I wanted to make the label clickable. I have tried using both, a linklabel and a regular label. I'm thinking no, but is there a trick to making what I just painted clickable?
 
Yes, that is the easy part, you see Graphics has a MeasureString method where you can get the size of the drawn text. Size and location is a Rectangle, conveniently Rectangle type has a Contains method that will tell you if a given Point is contained in the rectangle. Now you have all tools available to see if a mouse down location is hits the label rectangle or not.

This sample code also adds a border to the "label" so it is easier to see the rectangle, first define a Rectangle variable:
VB.NET:
Private labelrectangle As Rectangle
The Paint code, using MeasureString, defining the Rectangle, paiting:
VB.NET:
Dim s As String = "label text"
Dim sz As SizeF = e.Graphics.MeasureString(s, Me.Font, Me.PictureBox1.Width)
labelrectangle = New Rectangle(Point.Empty, Size.Round(sz))
Using b As New SolidBrush(Me.ForeColor)
    e.Graphics.DrawString(s, Me.Font, b, labelrectangle)
    e.Graphics.DrawRectangle(Pens.Red, labelrectangle)
End Using
The MouseDown code, using the defined Rectangle to hit-test the mouse location:
VB.NET:
If labelrectangle.Contains(e.Location) Then
    MessageBox.Show("""label"" was clicked")
End If
 
Great, the difficult part using Paint event and Graphics is of course the lack of design time support to place and size things accurately with drag-drop.

It is still possible to see the drawing at design time, if you create an inherited control and place the drawing in the class code (Paint or OnPaint) it will appear also in designer, just rebuild to see changes in code right away. This is what I mean:
VB.NET:
Public Class SpecialPictureBox
    Inherits PictureBox

'add code

End Class
After adding such class rebuild and this control appears Toolbox (app Components), then you would use this control instead of the default PictureBox class.
 
Yes, that is the easy part, you see Graphics has a MeasureString method where you can get the size of the drawn text. Size and location is a Rectangle, conveniently Rectangle type has a Contains method that will tell you if a given Point is contained in the rectangle. Now you have all tools available to see if a mouse down location is hits the label rectangle or not.

This sample code also adds a border to the "label" so it is easier to see the rectangle, first define a Rectangle variable:
VB.NET:
Private labelrectangle As Rectangle
The Paint code, using MeasureString, defining the Rectangle, paiting:
VB.NET:
Dim s As String = "label text"
Dim sz As SizeF = e.Graphics.MeasureString(s, Me.Font, Me.PictureBox1.Width)
labelrectangle = New Rectangle(Point.Empty, Size.Round(sz))
Using b As New SolidBrush(Me.ForeColor)
    e.Graphics.DrawString(s, Me.Font, b, labelrectangle)
    e.Graphics.DrawRectangle(Pens.Red, labelrectangle)
End Using
The MouseDown code, using the defined Rectangle to hit-test the mouse location:
VB.NET:
If labelrectangle.Contains(e.Location) Then
    MessageBox.Show("""label"" was clicked")
End If



This is great! Just what I needed. But how do you force the image to update.

I want to put a counter over a picture. So when I click on the counter, it will advance, and also when I change a combo box entry it will change to whatever is in the combo box. I have it working, except the display of the drawn text does not update. I have tried updating the picturebox, with picturebox.update.
 
Update will only make the control repaint invalidated areas, so if you haven't invalidated anything then nothing gets painted. You can invalidate with the Invalidate method, or call Refresh method which invalidates the whole control and then call Update for you. This is also explained for Control.Update Method in help.
 
Back
Top