0

I designed a user control with several controls inside. I drag and drop my user control on my form, then I set a mouse hover event for it to show a comment somewhere.

But there is a problem, the user should hover the mouse on the UserControl Container to see that comment, If He hovers the mouse on one of the controls inside the UserControl nothing will happen.

How to set mouse hover (or other events) to be raised on the UserControl and All of its children?

Inside Man
  • 4,194
  • 12
  • 59
  • 119
  • All child controls receive mouse events separately. As an option you can subscribe for the desired mouse event for all controls and raise the desired one for your user control. – Reza Aghaei Jun 16 '18 at 07:28
  • could you please show me some code, Amu Reza? :) – Inside Man Jun 16 '18 at 07:39

1 Answers1

2

All child controls receive mouse events separately. As an option you can subscribe for the desired mouse event for all controls and raise the desired one for your user control.

For example, in the following code, I've raised the container Click, DoubleClick, MouseClick, MouseDoubleClick and MouseHover event, when the corresponding event happens for any of the children in controls hierarchy:

public UserControl1() {
    InitializeComponent();
    WireMouseEvents(this);
}
void WireMouseEvents(Control container) {
    foreach (Control c in container.Controls) {
        c.Click += (s, e) => OnClick(e);
        c.DoubleClick += (s, e) => OnDoubleClick(e);
        c.MouseHover += (s, e) => OnMouseHover(e);

        c.MouseClick += (s, e) => {
            var p = PointToThis((Control)s, e.Location);
            OnMouseClick(new MouseEventArgs(e.Button, e.Clicks, p.X, p.Y, e.Delta));
        };
        c.MouseDoubleClick += (s, e) => {
            var p = PointToThis((Control)s, e.Location);
            OnMouseDoubleClick(new MouseEventArgs(e.Button, e.Clicks, p.X, p.Y, e.Delta));
        };

        WireMouseEvents(c);
    };
}

Point PointToThis(Control c, Point p) {
    return PointToClient(c.PointToScreen(p));
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Are all of the `On*` methods the handlers? – Enigmativity Jun 16 '18 at 07:57
  • @Enigmativity They are not handlers, they are protected methods of the control, responsible to raise the event. – Reza Aghaei Jun 16 '18 at 07:59
  • So you're getting the handlers on the child controls to raise the event on the parent `UserControl`? – Enigmativity Jun 16 '18 at 08:16
  • @Enigmativity For each child control in the control hierarchy, I subscribe to the mouse event of the child control and in the event handler, I raise `UserControl` corresponding event. For example, I subscribe to Click event of the child, and raise the `Click` event of the `UserControl`. This way, wherever you click, `Click` event of the `UserControl` will raise. – Reza Aghaei Jun 16 '18 at 08:20
  • If by your first comment, you mean `On*` methods are working as handlers, somehow yes, I use them in body of event handlers. `c.Click += (s, e) => OnClick(e);` is equivalent to `c.Click += (s, e) => { OnClick(e); };` – Reza Aghaei Jun 16 '18 at 08:24
  • @RezaAghaei let say we only need hover event. It is not working on my side on all of the controls inside the user control. for example it is not working if there is combobox inside the user control – Inside Man Jun 16 '18 at 08:27
  • After you drop an instance of `UserControl1` on the form, you should subscribe to `Hover` event of the `UserControl1`. The `ComboBox` will not raise `MouseHover` on the `Text` area. It's not related to the solution which we used. The event will raise for `DropdownButton` area. – Reza Aghaei Jun 16 '18 at 08:32
  • Nice Reza, and as a side question, is there any way to prevent hover on UserControl area and only raise it on checkbox controls inside the UserControl? – Inside Man Jun 16 '18 at 08:51
  • In this case, I'd prefer to change the solution a bit... for example you can override `OnMouseHover` and check a flag to see if you should call the base method or not. – Reza Aghaei Jun 16 '18 at 09:00