views:

4516

answers:

4

I have a mouseenter and mouseleave event for a Panel control that changes the backcolor when the mouse enters and goes back to white when it leaves.

I have Label control within this panel as well but when the mouse enters the Label control, the mouseleave event for the panel fires.

This makes sense but how do I keep the backcolor of the Panel the same when the mouse is in its area without the other controls inside affecting it?

A: 

You could add a MouseEnter event for the label which also sets the Panel's back colour. You wouldn't need a MouseLeave event for the label.

Or:

  1. Set the MouseEnter event for the Panel to set the Panel's back colour.
  2. Set the Panel's parent control's (e.g. the Form) MouseEnter event to reset the Panel's back colour.


If you wanted to do point 2 above without touching the parent control's code (as per other user's comment), you could do something like this in the Panel's ParentChanged event:

    private void panel1_ParentChanged(object sender, EventArgs e)
    {
        Panel thisPanel = sender as Panel;

        if(thisPanel != null && thisPanel.Parent != null)
        {
            thisPanel.Parent.MouseEnter += delegate(object senderObj, EventArgs eArgs) { thisPanel.BackColor = SystemColors.Control; };
        }
    }
ng5000
+1  A: 

Adding an event for a contained control means that when you want to add another control to the panel, you have to go through the same exercise for that too.

Adding an event for the parent control means that as soon as you want to use the panel somewhere else, you have to do the same for the new parent. And when the requirements for the panel change, you have to remember to take the processing out of the parent control's event.

All potentially messy a little further down the line.

I'd be inclined to put some coordinate checking in the mouse leave event for the panel, and only reset the panel colour if the mouse has really gone outside the bounds of the panel.

That way, your code for panel-handling remains only on the panel in question.

ChrisA
+1  A: 

I found a simple solution. I just set the enabled property to false on the label and it's fine.

Sir Psycho
... it'll be fine until you want an enabled control on your panel :)
ChrisA
Nice simple solution! Helped me with my specific case as well. It would be nice if there was some way to set up parent control to preview mouse events, before they are send to child controls, though.
Andy
+2  A: 

You can use GetChildAtPoint() to determine if the mouse is over a child control.

private void panel1_MouseLeave(object sender, EventArgs e)
{
    if (panel1.GetChildAtPoint(panel1.PointToClient(MousePosition)) == null)
    {
        panel1.BackColor = Color.Gray;
    }
}

If the control isn't actually a child control, you can still use MousePosition and PointToScreen to determine if the mouse is still within the bounds of the control.

private void panel1_MouseLeave(object sender, EventArgs e)
{
    Rectangle screenBounds = new Rectangle(this.PointToScreen(panel1.Location), panel1.Size);
    if (!screenBounds.Contains(MousePosition))
    {
        panel1.BackColor = Color.Gray;
    }
}
Jon B