I have a PictureBox inside a Panel, to get automatic scrollbars when the picture is big, a Label with the photo title.
If I place the Label over the PictureBox, the "transparent" backcolor shows correctly but the Label remains at the top of the PictureBox and gets out of the screen if I scroll up-down or side-side the Panel's scrollbar!
Instead, if I put the Label outside the Panel (over the Form), the Label remains static on top of the screen, as I want, but the transparent backcolor doesn't show correctly becomes opaque.
Then if I set the Label's Parent property to the PictureBox, the transparent backcolor works fine again, but the static position of the Label is not respected anymore and joins PictureBox again!
How can I get a static Label with transparent backcolor over a PictureBox when using the scrollbars of the Panel?
I've tested the Overlay Form. It seems to work pretty well in your context.
Source Code in PasteBin
Uploaded the modified Project in OneDrive
(I don't have FW 4.5.2, tested with FW 4.5.1 and FW 4.7.1)
An Overlay can be an interesting feature, but, as I already said, this can also be done with TextRender.DrawText()
or Graphics.DrawString()
, backed by the simple math needed to offset the painted text when the picture container is scrolled.
Label1
and all references to it.Private OverlayShown As Boolean = False
In frmPho_Load()
Overlay.Size = New Size(200, 50)
Overlay.OverlayPosition = Overlay.Alignment.Center
Overlay.Reposition(Me.Location, Me.Size)
OverlayShown = True
Overlay.Visible = False
Overlay.Show(Me)
In frmPho_Deactivate()
:
If OverlayShown = False Then
antip.Width = Me.Width
antip.Height = Me.Height
antip.Visible = True
End If
OverlayShown = False
These are all the changes made to the hosting Form (Form4
), the form that uses the Overlay.
Public Class frmPho
Private Overlay As New OverlayForm
Private Sub frmPho_Load(sender As Object, e As EventArgs) Handles Me.Load
Overlay.Size = New Size(200, 50)
Overlay.OverlayPosition = Overlay.Alignment.Center
Overlay.Reposition(Me.Location, Me.Size)
OverlayShown = True
Overlay.Visible = False
Overlay.Show(Me)
'(...)
Overlay.Text = IO.Path.GetFileNameWithoutExtension(_ImageFileNames(_CurrentImage))
End Sub
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
If CheckBox1.CheckState = False Then
Overlay.Visible = False
Else
OverlayShown = True
Overlay.Visible = True
End If
End Sub
Private Sub ShowPrevImage()
'(...)
OverlayShown = True
Overlay.Text = IO.Path.GetFileNameWithoutExtension(_ImageFileNames(_CurrentImage))
End Sub
Private Sub ShowNextImage()
'(...)
OverlayShown = True
Overlay.Text = IO.Path.GetFileNameWithoutExtension(_ImageFileNames(_CurrentImage))
End Sub
Private Sub frmPho_Deactivate(sender As Object, e As EventArgs) Handles Me.Deactivate
If OverlayShown = False Then
antip.Width = Me.Width
antip.Height = Me.Height
antip.Visible = True
End If
OverlayShown = False
End Sub
Private Sub frmPho_Move(sender As Object, e As EventArgs) Handles Me.Move
Overlay.Reposition(Me.Location, Me.Size)
End Sub
Private Sub frmPho_Resize(sender As Object, e As EventArgs) Handles Me.Resize
Overlay.Reposition(Me.Location, Me.Size)
End Sub
Private Sub frmPho_Shown(sender As Object, e As EventArgs) Handles Me.Shown
ShowOverlay(300)
End Sub
Private Async Sub ShowOverlay(Delay As Integer)
Await Task.Delay(Delay)
Overlay.Visible = True
Me.Focus()
End Sub
And this is the complete OverlayForm:
All Borders/Control Boxes to None (It's a borderless Form)
.StartPosition = Manual
.TransparncyKey = WhiteSmoke <= Depends on the font color (mod. when needed)
.BackColor = WhiteSmoke <= Depends on the font color (mod. when needed)
.ShowInTaskbar = False
Public Class OverlayForm
Private _Text As String
Private TextPosition As Point
Private _Brush As SolidBrush = New SolidBrush(Color.White)
Private _Flags As StringFormatFlags = StringFormatFlags.NoWrap
Public Enum Alignment
Left = 0
Right = 1
Center = 2
End Enum
Public Sub New()
InitializeComponent()
End Sub
Public Overrides Property Text() As String
Get
Return Me._Text
End Get
Set(ByVal value As String)
_Text = value
Me.Invalidate()
End Set
End Property
Public Property OverlayPosition As Alignment
Private Sub OverlayForm_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit
e.Graphics.TextContrast = 12
Dim _Size As SizeF = e.Graphics.MeasureString(Me._Text, Me.Font,
New SizeF(Me.Width, Me.Height),
New StringFormat(Me._Flags))
e.Graphics.DrawString(Me._Text, Me.Font, Me._Brush, New RectangleF(TextAlign(_Size.Width), _Size))
End Sub
Private Sub OverlayForm_ForeColorChanged(sender As Object, e As EventArgs) Handles Me.ForeColorChanged
Me._Brush = New SolidBrush(Me.ForeColor)
Me.Invalidate()
End Sub
Public Sub Reposition(ParentPosition As Point, ParentSize As Size)
Select OverlayPosition
Case Alignment.Left
Me.Location = New Point(ParentPosition.X + 20, ParentPosition.Y + 40)
Case Alignment.Right
Me.Location = New Point(ParentSize.Width - Me.Width - 20, ParentPosition.Y + 40)
Case Alignment.Center
Me.Location = New Point(ParentPosition.X + 20 + (ParentSize.Width \ 2) - (Me.Width \ 2), ParentPosition.Y + 40)
End Select
End Sub
Private Function TextAlign(TextWidth As Single) As PointF
Select Case OverlayPosition
Case Alignment.Left
Return New PointF(1, 1)
Case Alignment.Right
Return New PointF((Me.Width - TextWidth) - 1, 1)
Case Alignment.Center
If TextWidth > Me.Width Then TextWidth = Me.Width - 2
Return New PointF(CSng((Me.Width - TextWidth) / 4) - 1, 1)
End Select
End Function
End Class