本文介绍了子控件的触发面板事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

当我在 panel1 上移动鼠标时,事件会正确触发,但是当鼠标光标移动到 panel1 控件(如pictureBox)上时,该事件不起作用.当鼠标光标位于子控件上时,如何使事件被调用.

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.

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

最好的问候

推荐答案

你可以添加一个 IMessageFilter 来为你的 Panel 实现你自己的 global MouseHover代码>像这样:

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

注意:上面的代码用于面板中任何级别的嵌套控件.如果您的面板仅包含停止在级别 1 的子控件.您可以使用 c = Control.FromChildHandle(m.Hwnd) 稍微更改代码并通过 c== 检查控件的父控件panel1 而不必使用 HasParent 方法来检查子-祖先关系.

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.

这篇关于子控件的触发面板事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 23:00