fire panel events for child controls

核能气质少年 提交于 2021-02-11 17:22:12

问题


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


回答1:


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.




回答2:


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




回答3:


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.



来源:https://stackoverflow.com/questions/19089095/fire-panel-events-for-child-controls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!