0

I'm trying to do something that actually looks "simple" since several hours, but I cannot understand how to do it...and lurking over SO or different sites it seems that maybe is not that obvious.

The question is simple: i have a tableLayoutPanel with multiple rows, each one of them contains a panel, that contains several other controls.

I just want that when the mouse enters a row, the row background changes and when the mouse leave that row, it comes back to original color.

These are the simple event trappers, where pnlLayoutRow is the name of the panel containing the other controls:

Private Sub devRowMouseEnter(sender As System.Object, e As EventArgs) Handles pnlLayoutrow.MouseEnter
    pnlLayoutrow.BackColor = Drawing.Color.FromArgb(&HFFFFEEAA)
End Sub

Private Sub devRowMouseLeave(sender As System.Object, e As EventArgs) Handles pnlLayoutrow.MouseLeave
    pnlLayoutrow.BackColor = Drawing.Color.FromArgb(&HFFE7DEBD)
End Sub

The problem is: mouseEnter is correctly fired each time I enter the row, but Mouseleave is fired as soon as the mouse reach one of the controls inside the panel..that drives me crazy.

In other environment, I would solve this placing a transparent object all over the panel and trapping the mouseEnter and leave for that object..but it seems in VB trasparent objects do not exist.

Hope I have been clear in my explanation..it is pretty late in the night and I'm a bit tired.

thank you in advance hope someone can help me

Cristiano

Cristiano Zambon
  • 466
  • 5
  • 14

1 Answers1

1

This version of your mouse leave event checks that the mouse is still within the bounds of your TableLayoutPanel and if it is then it exits without changing the color

Private Sub devRowMouseLeave(sender As System.Object, e As EventArgs) Handles pnlLayoutRow.MouseLeave
    Dim p As Point = Me.PointToClient(MousePosition)
    If p.Y > pnlLayoutRow.Top And p.Y < (pnlLayoutRow.Top + pnlLayoutRow.Height) And p.X > pnlLayoutRow.Left And p.X < (pnlLayoutRow.Left + pnlLayoutRow.Width) Then
        Exit Sub
    Else
        pnlLayoutRow.BackColor = Drawing.Color.FromArgb(&HFFE7DEBD)
    End If
End Sub

It seems to work ok for me,so I hope it is the same for you.

I've had a Google about mouse polling rates and by default, in windows, it's 125hz which might seem OK. However, if you move the mouse quickly, the mouse will enter and leave the panel more quickly that windows can detect it. Because of this, sometimes the .MouseEnter and .MouseLeave events don't fire. So I have here an alternative which will at least detect when the mouse leaves the panel. Add a Timer you your form called tmrPanelLeave

Private Sub devRowMouseEnter(sender As System.Object, e As EventArgs) Handles pnlLayoutRow.MouseEnter
    pnlLayoutRow.BackColor = Drawing.Color.FromArgb(&HFFFFEEAA)
    tmrPanelLeave.Start()
End Sub

Private Sub tmrPanelLeave_Tick(sender As Object, e As EventArgs) Handles tmrPanelLeave.Tick
    Dim p As Point = Me.PointToClient(MousePosition)
    If p.Y > pnlLayoutRow.Top And p.Y < (pnlLayoutRow.Top + pnlLayoutRow.Height) And p.X > pnlLayoutRow.Left And p.X < (pnlLayoutRow.Left + pnlLayoutRow.Width) Then
        Exit Sub
    Else
        pnlLayoutRow.BackColor = Drawing.Color.FromArgb(&HFFE7DEBD)
        tmrPanelLeave.Stop()
    End If
End Sub
David Wilson
  • 4,369
  • 3
  • 18
  • 31
  • really nice, let me try it and I'll let you know, thank you! – Cristiano Zambon Feb 04 '16 at 21:29
  • tried...it acutally doe not work fine. If when I start the mouse move the pointer is on a inner control, and I move out the mouse fast so it does not pass though the panel itself but it jumps from the inner control directly to outside of the user control, the mouseleave event is not fired. – Cristiano Zambon Feb 04 '16 at 21:34
  • That will be because of the information that windows provides to the program. You could move the code into the mouse. Move event. Be warned though, this might make your mouse movement laggy. If you have other code in the mouse move event then you might need to remove the "Exit Sub" line. – David Wilson Feb 04 '16 at 21:55
  • Hi Christiano - I've just had another look at the code I wrote and for some reason it isnt working now. - I'll get back to you. – David Wilson Feb 06 '16 at 10:47
  • @Christiano ok. I've written an alternative bit of code into my answer. This should work better for the .MouseLeave event. There's not much I can do about the .MouseEnter event unless you want the timer running all the time. Let me know. – David Wilson Feb 06 '16 at 11:01
  • No problem. Glad to help. – David Wilson Feb 06 '16 at 19:12