3

I am testing the following code:

protected override void OnMouseMove(MouseEventArgs e)
{
    base.OnMouseMove(e);
    Rectangle leftRect = new Rectangle(0, 0, 32, this.Height);
    if (leftRect.Contains(e.Location))
    {
        MessageBox.Show("Hello World");
    }
}

The idea is that when the mouse enters a region 32 pixels wide, to the left of the container control, a message appears (OK, in R/L it will do something else, but this is purely testing for now).

The issue is that when a child control populates the rectangle region, the ContainerControl does not receive the MouseMove event, as it is being handled by the child control.

So my question is, how to I get my ContainerControl to receive the MouseMove event, even when its children populate the same rectangle region?

Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
  • @JohnKoerner it is probably important to note that forcing the child controls to be transparent removes them from the event chain completely - you lose the ability for each child control to have its own `MouseMove` code since the event drills directly to the parent control. The method below allows the child controls to retain their ability to handle the move event but also to bubble the event up to top control. – J... Feb 11 '13 at 15:10

1 Answers1

2

WPF is a lot better at this sort of thing. I use a function like this a lot :

public static List<Control> GetAllControlsRecurs(List<Control> list, 
                                                 Control parent)
{
    if (parent == null)
        return list;
    else
    {
        list.Add(parent);
    }
    foreach (Control child in parent.Controls)
    {
        GetAllControlsRecurs(list, child);
    }
    return list;
}

This returns a list of all child controls and their children, etc, within a given parent control. You could then do something like :

private void Form1_Load(object sender, EventArgs e)
{
    List<Control> ctlList = new List<Control>();
    GetAllControlsRecurs(ctlList, this);
    foreach (Control ctl in ctlList) ctl.MouseMove += Form1_MouseMove;
}

You would have to handle dynamically added (and removed) controls with ControlAdded but this should at least give you a start. Note here that this will not execute code in the overriden OnMouseMove method but rather in the form's MouseMove event handler. There are a number of other solutions for building this into a derived class but the important point here is the means of identifying and hooking up child controls to a single event.

J...
  • 30,968
  • 6
  • 66
  • 143
  • Hi, thanks for this answer. I'm not overly experienced with WPF (although I should be, as WinForms seems to be on the decline). – Matthew Layton Feb 12 '13 at 09:42