Reputation: 1410
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
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
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
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