0

我有一个名为 panel1 的面板。panel1 有一个“mosuseHover”事件处理程序。panel1 也有一些控件,如图片框、标签等。

当我在 panel1 上移动鼠标时,事件会正确触发,但是当鼠标进程继续在 panel1 控件上时,例如 pictureBox,事件不起作用。当鼠标 courser 在子控件上时,如何使事件被调用。

我应该注意,我不想为每个子控件创建事件处理程序。

此致

4

3 回答 3

5

您可以像这样添加一个IMessageFilter来实现您自己global MouseHoverPanel

//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;
    }
}

注意:上面的代码被实现为适用Panel. c = Control.FromChildHandle(m.Hwnd)如果您的面板仅包含在级别 1 停止的子控件。您可以通过使用并检查控件的父级来稍微​​更改代码,c==panel1而无需使用该HasParent方法来检查子-祖先关系。

于 2013-09-30T08:21:48.547 回答
1

您可以在子级上创建一个事件处理程序,并使用相同的参数简单地调用面板处理程序。也看看这个线程

于 2013-09-30T08:01:37.053 回答
0

我反驳了同样的问题。我通过创建一个 MouseEnter 事件来解决它,并在其中声明Control ctl = sender 为 Control ; 然后我调用了ctl的Parent,Control panel = ctl.Parent; 现在做任何你想做的事,如panel.BackColor = Color.Red;

像这样:

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 
        }
    }

但是不要忘记遍历所有控件并获取面板以及面板内的任何内容。像这样:

        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);
                        }
                    }
                }
            }
        }

你可以弄清楚其余的。希望这可以帮助。

于 2013-10-30T20:07:07.393 回答