我有一个名为 panel1 的面板。panel1 有一个“mosuseHover”事件处理程序。panel1 也有一些控件,如图片框、标签等。
当我在 panel1 上移动鼠标时,事件会正确触发,但是当鼠标进程继续在 panel1 控件上时,例如 pictureBox,事件不起作用。当鼠标 courser 在子控件上时,如何使事件被调用。
我应该注意,我不想为每个子控件创建事件处理程序。
此致
您可以像这样添加一个IMessageFilter
来实现您自己global MouseHover
的Panel
:
//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
方法来检查子-祖先关系。
您可以在子级上创建一个事件处理程序,并使用相同的参数简单地调用面板处理程序。也看看这个线程
我反驳了同样的问题。我通过创建一个 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);
}
}
}
}
}
你可以弄清楚其余的。希望这可以帮助。