【问题标题】:Scrolling a Picturebox inside a Panel with a static label over在具有静态标签的面板内滚动图片框
【发布时间】:2018-07-04 06:52:26
【问题描述】:

我在 Panel 中有一个 PictureBox,用于在图片很大时获得自动滚动条,一个带有照片标题的 Label。
如果我将 Label 放在 PictureBox 上,“透明”背景颜色会正确显示,但 Label 仍位于 PictureBox 的顶部,并且如果我向上或向下滚动面板的滚动条,它就会离开屏幕!

相反,如果我将标签放在面板之外(在表单上方),标签会如我所愿在屏幕顶部保持静态,但透明背景色无法正确显示,会变为不透明。

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

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

【问题讨论】:

  • 请添加您现有的代码,以便我们弄清楚发生了什么?
  • @Sunil 创建 1 个图片框、1 个面板、1 个透明标签 .backcolor 到标签 - 在面板自动滚动 - 加载图片并自动调整大小。面板内的图片框。在 Picturebox 上添加标签。添加:Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.LoadLabel1.Parent = PictureBox1End Sub使用滚动条,标签出来了!现在将标签移出图片框更改所有代码Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.LoadLabel1.Left = 45End Sub(以编程方式)设置标签在图片上的位置。现在移动滚动条
  • @Sunil 你看到了吗?如果您以编程方式设置 Label 位置,Label 会松开透明背景色,但如果您将 PictureBox 设为 .parent,则静态位置会松开!我还尝试添加计时器以每秒重新定位或重新定位到 Form,然后快速重新定位到 PictureBox,但这不起作用!如何获得透明和静态标签?
  • 你可以用一个覆盖层来做到这一点,使用一个透明的孪生形式。在另一个控件上绘制控件,在滚动时总是会导致闪烁。叠加层更好。如果您有兴趣,请回电。
  • @Jimi 我无法将表单与其他表单散焦,因为我在 PictureBox 上设置了标签以保护第三个快照软件,在这篇文章中他们提供了一个解决方案:stackoverflow.com/questions/9387267/… 但我无法适应我的vb.net 项目..

标签: vb.net winforms scrollbar panel picturebox


【解决方案1】:

我已经测试了覆盖表单。它似乎在您的上下文中运行良好。
PasteBin中的源代码
将修改后的项目上传到OneDrive
(我没有 FW 4.5.2,用 FW 4.5.1 和 FW 4.7.1 测试过)

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


在您的项目中,我删除了 Label1 以及所有对它的引用。
然后,我设置了这个类字段:
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:

所有边框/控制框都为无(这是一个无边框的表单)
.StartPosition = 手动
.TransparncyKey = WhiteSmoke 取决于字体颜色(需要时修改)
.BackColor = WhiteSmoke 取决于字体颜色(需要时修改)
.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

【讨论】:

  • 如果您标记 2 次 checkbox1,“未经授权的图层”将变为可见...
  • CheckBox1_CheckedChanged() 事件中,在Else 部分,只需通知显示叠加层:(...) Else OverlayShown = True Overlay.Visible = True。每次必须显示覆盖时都执行相同的操作。我会将它添加到代码的 Changes 部分。
猜你喜欢
  • 2010-12-22
  • 1970-01-01
  • 1970-01-01
  • 2017-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 2017-07-21
相关资源
最近更新 更多