0

I have a Panel named panel1. panel1 has a "mosuseHover" eventhandler .panel1 also has some controls like pictureBox , label etc.

When i move mouse on panel1 , the event fire correctly , but when the mouse courser goes on panel1 controls , like pictureBox , the event not work . how can i make event to be invoke when mouse courser is on child controls.

I should note that i dont want create eventhandler for each child contol.

Best Regards

AmirHossein Rezaei
  • 1,086
  • 1
  • 16
  • 20
  • Why you don't want to create eventhandler for each control when you want such behavior? If you want MouseHover, you need to specify proper event handler for any control that should fire it. Btw. you can specify the same eventHandler for each control – Nikola Davidovic Sep 30 '13 at 08:15
  • Thank you for your notation.I can not do it becuase of two problem: 1-invoking many events reduse my program speed. 2-I have some graphical problem ..... – AmirHossein Rezaei Oct 02 '13 at 14:21

3 Answers3

5

You can add an IMessageFilter to implement your own global MouseHover for your Panel like this:

//This code uses some reflection so you must add using System.Reflection
public partial class Form1 : Form, IMessageFilter
{
     public Form1(){
       InitializeComponent();
       Application.AddMessageFilter(this);
     }
     public bool PreFilterMessage(ref Message m) {
        Control c = Control.FromHandle(m.HWnd)
        if (HasParent(c,panel1)){                
            if (m.Msg == 0x2a1){//WM_MOUSEHOVER = 0x2a1
                //Fire the MouseHover event via Reflection
                typeof(Panel).GetMethod("OnMouseHover", BindingFlags.NonPublic | BindingFlags.Instance)
                    .Invoke(panel1, new object[] {EventArgs.Empty});                    
            }
        }
        return false;
    }
    //This method is used to check if a child control has some control as parent 
    private bool HasParent(Control child, Control parent) {
        if (child == null) return false;
        Control p = child.Parent;
        while (p != null) {
            if (p == parent) return true;
            p = p.Parent;
        }
        return false;
    }
}

NOTE: The code above is implemented to work for nested controls of any level in your Panel. If your panel contains only child controls stopping at level 1. You can change the code a bit by using c = Control.FromChildHandle(m.Hwnd) and check the control's parent by c==panel1 without having to use the HasParent method to check for child-ancestor relationship.

King King
  • 61,710
  • 16
  • 105
  • 130
1

You may create an eventhandler on the children and simply call the panels handler with the same arguments. Also have a look at this thread

Community
  • 1
  • 1
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
0

I countered the same problem. I solved it by creating a MouseEnter event and in it I declared Control ctl = sender as Control; Then I called ctl's Parent, with, Control panel = ctl.Parent; Now do whatever you want, as in panel.BackColor = Color.Red;

Like this:

private void label_MouseEnter(object sender, System.EventArgs e)
    {
        Control ctl = sender as Control; // gets the label control
        Control panel = ctl.Parent; // gets the label's parent control, (Panel in this case)
        if (ctl != null)
        {
            ctl.Font = new Font(ctl.Font.Name, 11, FontStyle.Underline); // change the font of the Label and style...
            panel.BackColor = Color.Blue; // change the panel's backColor
            ctl.Cursor = Cursors.Hand;
            // do more with the panel & label 
        }
    }

But don't forget to iterate through all the controls and to get the Panel and whatever that's inside the Panel. Like this:

        public YourApp()
        {
            InitializeComponent();
            foreach (Control objCtrl in this.Controls) // get all the controls in the form
            {

                if (objCtrl is Panel) // get the Panel
                {
                    objCtrl.MouseEnter += new EventHandler(panel_MouseEnter); // do something to the panel on MouseEnter
                    objCtrl.MouseLeave += new EventHandler(panel_MouseLeave);
                    foreach (Control ctl in objCtrl.Controls) // get all the controls inside the Panel
                    {
                        if (ctl is Label) // get the label inside the panel
                        {
                            ctl.MouseEnter += new System.EventHandler(label_MouseEnter);
                            ctl.MouseLeave += new EventHandler(label_MouseLeave);
                            ctl.Click += new EventHandler(label_Click);
                        }
                        if (ctl is PictureBox) // get the pictureBox inside the panel
                        {
                            ctl.MouseEnter += new EventHandler(label_MouseEnter);
                        }
                    }
                }
            }
        }

You can figure out the rest. Hope this helps.

Zubair
  • 248
  • 3
  • 9