【问题标题】:PictureBox MouseEnter / MouseLeave Events not FiringPictureBox MouseEnter / MouseLeave 事件未触发
【发布时间】:2013-06-06 20:12:49
【问题描述】:

创建一个包含三个图片框的新表单。此代码旨在在鼠标进入图片框时绘制边框,并在离开时将其移除。结果不一致。有时它会绘制/删除边框,有时则不会。这段代码并不复杂。使用 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控件里面有子控件吗?
  • 不,他们没有。新建表单,添加三个图片框和上面的代码。
  • 什么平台; Winforms,WPF?
  • 好的,我可以重现它,虽然看起来只有 MouseLeave 有时不会触发。奇怪。
  • 更改 BorderStyle 属性有太多副作用,原生窗口被破坏并重新创建。这使它忘记了鼠标输入。您需要选择其他东西来指示状态。你可以很容易地画出类似的东西。

标签: vb.net winforms


【解决方案1】:

我也可以重现该问题。因此,在上面关于“绘制其他东西”而不是使用 Picturebox 的属性的 cmets 上进行扩展,让我建议这种快速而肮脏的方法:

  • 使用 RectangleShape 对象,该对象由 VisualBasic Powerpack 3.0 插件提供。只需将其中一个放在与您的 PictureBox 相同的形式中,并使其不可见(可见 = 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 解释了。
  • @KingKing 正如上面的 cmets 中提到的,我知道有一些解决方法。我想知道为什么。在 BorderStyle 的文档中没有提到任何副作用。如果“原生窗口被破坏并重新创建”时事件丢失,为什么它会起作用。
  • @KalaNag - 如果事件没有被触发,看起来像正在发生的事情,那么这将不起作用。
  • @dbasnett 但问题是,虽然我确实看到了像你一样使用 BorderStyle 错过的事件,但我没有使用 RectangleShape 错过一个事件......即使将鼠标移动到高处也没有3 个图片框之间的速度:它总是对我有用。唯一的区别是,如果使用 3 个 PictureBox,则需要 3 个单独的事件处理程序,这没什么大不了的……
  • @KalaNag - 当您将鼠标缓慢移出图片框时,实际上似乎会发生这种情况,而不是高速移动。正如我所说,我的问题是不一致。
【解决方案2】:

需要 Form MouseEnter 事件的帮助..

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

【讨论】:

    【解决方案3】:

    我遵循 KalaNag 的想法,将我的图片框放在面板中,并通过这样做来处理图片框上的事件

    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;
    
        }
    

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

    像魅力一样工作!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-11
      • 2016-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多