如果调整窗体大小,如何使用鼠标坐标显示或隐藏面板?

How to show or hide a Panel using Mouse coordinates if the Form is resized?

我有一个包含面板的表单。
起初,这个面板是不可见的,当鼠标进入它的客户区时才可见。
只要我不调整表单的大小,我使用的代码就可以工作。
通过更改表单大小,此代码不再有效。

我试过这段代码:

Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
    Label1.Text = e.Location.ToString
    If e.Location.Y > 441 Then
        Panel1.Visible = True
    Else
        Panel1.Visible = False
    End If
End Sub

试试这个:

Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
    Label1.Text = e.Location.ToString

    If e.X > Panel1.Left And e.X < Panel1.Left + Panel1.Width And e.Y > Panel1.Top And e.Y < Panel1.Top + Panel1.Height Then
        Panel1.Visible = True
    Else
        Panel1.Visible = False
    End If
End Sub

由于此面板似乎停靠在窗体的底部,您可以只考虑面板的 Bounds(描述控件在其容器内占据的区域的矩形)来确定鼠标是否位置在其客户区内。

Rectangle.Contains(Point) 方法 returns TrueFalse 如果点包含在指定矩形的边界内。
然后,您还可以使用布尔结果来设置面板的可见性:

Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
    Panel1.Visible = Panel1.Bounds.Contains(e.Location)
End Sub

额外:
其他常见情况如何处理:

  • Panel1 不是 Form 的直接子级,因此当鼠标指针进入 Panel 实际父级的边界时,Form 不会接收鼠标事件
  • 窗体的客户区被其他控件覆盖,鼠标指针悬停在这些控件上时不会接收到鼠标事件

您不能将事件处理程序添加到表单中可能在某些时候参与这些操作的所有控件。可以在设计器中添加、删除或移动控件。不可行。

在这些和其他类似情况下,实施 IMessageFilter 会派上用场。
您可以使用 Application.AddMessageFilter / Application.RemoveMessageFilter 方法在将消息发送到目标之前监视定向到任何控件的消息。
如果需要,您还可以阻止消息到达目的地,在 IMessageFilter.PreFilterMessage() 方法中返回 True

这里,表单class直接实现了IMessageFilter。您当然可以创建一个可重用的助手 class 来做同样的事情。

Public Class SomeForm
    Implements IMessageFilter

    Private Const WM_MOUSEMOVE As Integer = &H200
    Public Sub New()
        InitializeComponent()
        Application.AddMessageFilter(Me)
    End Sub

    Protected Overrides Sub OnFormClosed(e As FormClosedEventArgs)
        Application.RemoveMessageFilter(Me)
        MyBase.OnFormClosed(e)
    End Sub

    Public Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
        If m.Msg = WM_MOUSEMOVE Then
            Panel1.Visible = Panel1.RectangleToScreen(Panel1.ClientRectangle).Contains(MousePosition)
        End If
        Return False
    End Function
End Class