AmirHossein Rezaei
AmirHossein Rezaei

Reputation: 1410

fire panel events for child controls

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

Upvotes: 0

Views: 2894

Answers (3)

Zubair
Zubair

Reputation: 238

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.

Upvotes: 0

King King
King King

Reputation: 63327

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.

Upvotes: 5

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37000

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

Upvotes: 1

Related Questions