使用Winforms和vb.net VS 2012:
如果我有一个大型可滚动面板,我在较大的面板内放了一堆较小的面板。当我向上或向下滚动较大的面板时,一些较小的面板将滚出视图。我的问题是,我可以在较小的面板上放置一个监听器,以便较小的面板知道它何时滚出视图?
我无法使用.visible属性,因为即使面板不在窗口中,它也始终设置为true。我也知道我可以设置.focus属性将其恢复到视图中,但只要其他东西成为焦点,它仍然会在可视窗口中失去焦点。
当面板滚出视图时,是否有可以侦听的属性或其他内容?如果没有,我还能做些什么来检测这个?
感谢。
答案 0 :(得分:0)
从Panel的Scroll()和MouseWheel()事件中,使用如下代码:
Private Sub Panel1_Scroll(sender As Object, e As ScrollEventArgs) Handles Panel1.Scroll
CheckVisibility(sender)
End Sub
Private Sub Panel1_MouseWheel(sender As Object, e As MouseEventArgs) Handles Panel1.MouseWheel
CheckVisibility(sender)
End Sub
Private Sub CheckVisibility(ByVal pnl As Panel)
Dim results As New List(Of String)
Dim pnlRectScreen As Rectangle = pnl.Parent.RectangleToScreen(pnl.Bounds)
For Each child As Control In pnl.Controls
Dim childRectScreen As Rectangle = pnl.RectangleToScreen(child.Bounds)
If pnlRectScreen.IntersectsWith(childRectScreen) Then
If pnlRectScreen.Contains(childRectScreen) Then
results.Add(child.Name & ": Completely Visible")
Else
results.Add(child.Name & ": Partially Visible")
End If
Else
results.Add(child.Name & ": Not Visible")
End If
Next
ListBox1.DataSource = Nothing
ListBox1.DataSource = results
End Sub
如果您想知道它何时变为隐藏,则使用Dictionary()跟踪当前可见性,并在其变为隐藏时执行某些操作。这是一个更强大的例子:
Public Enum ControlVisibility
Hidden
PartialyVisible
FullyVisible
End Enum
Private VisibiltyState As New Dictionary(Of Control, ControlVisibility)
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Dim pnl As Panel = Panel1
Dim pnlRectScreen As Rectangle = pnl.Parent.RectangleToScreen(pnl.Bounds)
For Each child As Control In pnl.Controls
Dim childRectScreen As Rectangle = Panel2.RectangleToScreen(child.Bounds)
If pnlRectScreen.IntersectsWith(childRectScreen) Then
If pnlRectScreen.Contains(childRectScreen) Then
VisibiltyState.Add(child, ControlVisibility.FullyVisible)
Else
VisibiltyState.Add(child, ControlVisibility.PartialyVisible)
End If
Else
VisibiltyState.Add(child, ControlVisibility.Hidden)
End If
Next
End Sub
Private Sub Panel1_Scroll(sender As Object, e As ScrollEventArgs) Handles Panel1.Scroll
CheckVisibility(sender)
End Sub
Private Sub Panel1_MouseWheel(sender As Object, e As MouseEventArgs) Handles Panel1.MouseWheel
CheckVisibility(sender)
End Sub
Private Sub CheckVisibility(ByVal pnl As Panel)
Dim NewVisibility As ControlVisibility
Dim pnlRectScreen As Rectangle = pnl.Parent.RectangleToScreen(pnl.Bounds)
For Each child As Control In pnl.Controls
Dim childRectScreen As Rectangle = pnl.RectangleToScreen(child.Bounds)
If pnlRectScreen.IntersectsWith(childRectScreen) Then
If pnlRectScreen.Contains(childRectScreen) Then
NewVisibility = ControlVisibility.FullyVisible
Else
NewVisibility = ControlVisibility.PartialyVisible
End If
Else
NewVisibility = ControlVisibility.Hidden
End If
' has it changed?
If VisibiltyState(child) <> NewVisibility AndAlso NewVisibility = ControlVisibility.Hidden Then
Debug.Print(child.Name & " has become hidden: " & DateTime.Now.ToString("h:mm:ss.ffff"))
End If
VisibiltyState(child) = NewVisibility
Next
End Sub