views:

495

answers:

1

I have a userControl (.NET 1.1 Winforms) that has a clickable picturebox as a button.

Since I have lots of those usercontrols visible at the same time, I thought It could be nice if I just display the picture box when the mouse is over the usercontrol and hide it otherwise.

To do so, I handle the MouseEnter and MouseLeave events of the UserControl, hiding and displaying the picturebox. That works fine.

But when the clickable picturebox is visible I'm not longer able to click it (the hand cursor is gone and the click event is not firing).

After some test, I realize that if comment all content on the MouseLeave handler that do something with my picturebox... this way the picturebox is clickable.

I'm not using the correct event?

There's another way to accomplish this?

Here is the code...

Private Sub NodoEstablo_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.pictAdd.Visible = False 
End Sub


Private Sub NodoEstablo_MouseEnters(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.MouseEnter        
    Me.pictAdd.Visible = True
End Sub

The problematic event handler:

Private Sub NodoEstablo_MouseLeaves(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.MouseLeave
    Me.pictAdd.Visible = False
End Sub

Update: If I resize the picturebox on MouseLeave (just to do something) it works. So far, changing Visible and Location in the MouseLeave prevent me for click the picturebox. :S

+3  A: 

When the mouse moves over your button, something similar to the following happens:

  1. The mouse leaves the usercontrol (even though it is still inside the control) and enters the picturebox
    • Your MouseLeave event handler fires, making the picturebox not visible
  2. Because the picturebox isn't visible, the mouse leaves the picturebox and enters the usercontrol
    • Your MouseEnter event handler fires, making the picturebox visible
  3. Because the picturebox is now visible, the process starts over from the beginning

When I tested your code, the "button" flickered continuously (as it kept having its visibility toggled) and was unable to stay visible long enough to register any clicks.

One way to address this is to modify your MouseLeaves handler to be something like this:

Private Sub NodoEstablo_MouseLeaves(ByVal sender As System.Object, _
                                    ByVal e As System.EventArgs) _
                                    Handles MyBase.MouseLeave
    If Not ClientRectangle.Contains(PointToClient(Cursor.Position)) Then
        Me.pictAdd.Visible = False
    EndIf
End Sub

This checks to make sure that the mouse has actually left the control before making the button disappear.

Changing the size of the picturebox may have broken the cycle outlined above, but it doesn't address the fundamental problem.

Here are some other things (that have nothing to do with your question) to consider:

  • I think that it's recommended that you just override the OnMouseLeaves, etc methods in your usercontrol, instead of subscribing to the corresponding events.
  • Remember that handling controls this way can make it impossible for someone to use your application with a keyboard only. (i.e. the user can't Tab to your button and press Enter)
Daniel LeCheminant
I was suspecting that something like that where happening, so I do the Hidding logic inside a timer... starting the timer when the mouse leaves and stopping it after hidding the button. Now I can get rid of the timer... Thanks a lot.
Romias