PictureBox的MouseEnter / MouseLeave事件无法触发

6

使用VS 2012创建一个包含三个图片框的新表单。这段代码旨在在鼠标进入图片框时绘制边框,并在鼠标离开时删除它。但结果不一致。有时会绘制/删除边框,有时不会。这段代码并不复杂。

Private Sub PictureBox_MouseEnter(sender As Object, e As EventArgs) _
    Handles PictureBox1.MouseEnter, PictureBox2.MouseEnter, PictureBox3.MouseEnter
    Dim pb As PictureBox = DirectCast(sender, PictureBox)
    pb.BorderStyle = BorderStyle.FixedSingle
    ' Debug.WriteLine("E " & pb.Name)
End Sub

Private Sub PictureBox_MouseLeave(sender As Object, e As EventArgs) _
    Handles PictureBox1.MouseLeave, PictureBox2.MouseLeave, PictureBox3.MouseLeave

    Dim pb As PictureBox = DirectCast(sender, PictureBox)
    pb.BorderStyle = BorderStyle.None
    ' Debug.WriteLine("X " & pb.Name)
End Sub

你的 PictureBox 控件里面有子控件吗? - EkoostikMartin
不,他们不会。新建一个表单,添加三个图片框和上面的代码。 - dbasnett
1
好的,我可以重现它,虽然看起来只有“MouseLeave”有时没有触发。奇怪。 - EkoostikMartin
该平台是Winforms。 - dbasnett
2
更改BorderStyle属性会产生太多的副作用,本地窗口会被销毁并重新创建。这使得它忘记了鼠标进入的状态。您需要选择其他方式来指示状态。您可以轻松地绘制类似的东西。 - Hans Passant
显示剩余7条评论
3个回答

1
我也能重现这个问题。因此,在上面关于“绘制其他东西”而不是使用Picturebox属性的评论基础上,让我建议这种快速而简单的方法:
  • 使用RectangleShape对象,该对象由VisualBasic Powerpack 3.0插件提供。只需将其放置在与PictureBox相同的窗体中,并使其不可见(visible = false)。

  • 代码也很简单:

    Public Class Form1
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.RectangleShape1.Location = New Point(Me.PictureBox1.Left - 1, Me.PictureBox1.Top - 1)
            Me.RectangleShape1.Size = New Size(Me.PictureBox1.Width + 1, Me.PictureBox1.Height + 1)
        End Sub
    
        Private Sub PictureBox1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseEnter
            Me.RectangleShape1.Visible = True
        End Sub
        Private Sub PictureBox1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseLeave
            Me.RectangleShape1.Visible = False
        End Sub
    End Class
    

OP似乎不想用其他方法,因为这样有点简单,可以使用一些与图形相关的方法。问题是如何通过切换BorderStyle来实现它。我已经测试了1个PictureBox,效果很好,但是对于3个PictureBox,有些奇怪的事情发生了,也许可以由Hans Passant解释。 - King King
@KingKing 如上面的评论中所提到的,我知道有解决方法。但我想知道为什么。在BorderStyle的文档中没有提到任何副作用。如果事件在“本机窗口被销毁和重新创建”时丢失,为什么它还能正常工作呢? - dbasnett
@KalaNag - 如果事件没有被触发,看起来就像是正在发生的情况,那么这个方法将无法工作。 - dbasnett
@dbasnett 但问题是,虽然我像你一样使用BorderStyle看到了错过的事件,但我在使用RectangleShape时没有一个错过的事件...即使在3个PictureBox之间以高速移动鼠标时也是如此:它总是正常工作。唯一的区别是,如果您使用3个PictureBox,则需要3个单独的事件处理程序,这并不是什么大问题... - KalaNag
@KalaNag - 实际上,这似乎发生在你慢慢将鼠标移出图片框时,比高速移动更频繁。正如我所说,我的问题是不一致的。 - dbasnett

0

我按照KalaNag的想法,将我的picturebox放在一个面板中,并通过以下方式处理了picturebox上的事件

private void PictureBox_MouseEnter(object sender, EventArgs e)
    {
        PictureBox control = sender as PictureBox;

        (control.Parent as Panel).Width = 20;
        (control.Parent as Panel).Height = 20;
        (control.Parent as Panel).BorderStyle = BorderStyle.Fixed3D;

    }

    private void PictureBox_MouseLeave(object sender, EventArgs e)
    {
        PictureBox control = sender as PictureBox;

        (control.Parent as Panel).Width = 18;
        (control.Parent as Panel).Height = 18;
        (control.Parent as Panel).BorderStyle = BorderStyle.None;

    }

我改变了控件的大小,因为否则,当鼠标悬停在边框上并且光标无限期地进入和离开时,图片框会闪烁,因为边框改变了控件的大小。

非常完美!


0

需要在表单的鼠标进入事件中寻求一些帮助..

Dim pb As PictureBox = New PictureBox

Private Sub Form1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseEnter
   pb.BorderStyle = BorderStyle.None
End Sub

Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove

   pb = PictureBox1
   pb.BorderStyle = BorderStyle.FixedSingle

End Sub

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接