在带有静态标签的面板内滚动图片框

Scrolling a Picturebox inside a Panel with a static label over

我在 Panel 中有一个 PictureBox,当图片很大时可以自动滚动条,一个带有照片标题的 Label。
如果我将 Label 放在 PictureBox 上,“透明”背景色会正确显示,但如果我滚动 up-down 或 side-side Panel 的滚动条,Label 会保留在 PictureBox 的顶部并离开屏幕!

相反,如果我将 Label 放在 Panel 之外(在 Form 之上),Label 会如我所愿地在屏幕顶部保持静态,但透明的背景色无法正确显示,变成不透明的。

然后如果我将Label的Parent 属性设置为PictureBox,透明背景色又可以正常工作,但是Label的静态位置不再受尊重并再次加入PictureBox!

如何在使用 Panel 的滚动条时在 PictureBox 上获得带有透明背景色的静态标签?

我已经测试了叠加表单。它在您的上下文中似乎工作得很好。
PasteBin
中的源代码 在 OneDrive
中上传修改后的项目 (我没有 FW 4.5.2,用 FW 4.5.1 和 FW 4.7.1 测试过)

Overlay 可能是一个有趣的功能,但是,正如我已经说过的,这也可以通过 TextRender.DrawText()Graphics.DrawString() 来完成,由滚动图片容器时偏移绘制文本所需的简单数学支持.


在你的项目中,我删除了 Label1 和所有对它的引用。
然后,我设置了这个 class 字段:

Private OverlayShown As Boolean = False

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)

frmPho_Deactivate()中:

If OverlayShown = False Then
    antip.Width = Me.Width
    antip.Height = Me.Height
    antip.Visible = True
End If
OverlayShown = False


这些是对使用 Overlay 的托管表单 (Form4) 所做的所有更改。

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

这是完整的 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