3

I have a UserControlwhich contains some inner controls inside it. something like this:

enter image description here

Now when I use it in my project, I want every point of my control raise the same click event if clicked, just like other controls.

but the problem is: my handler in another project, handles click events just when I click somewhere on the background, not on the button1 or label1.

I can solve it by setting every event in inner controls raise another event for the main control, but it is a bit odd.

How can I make the inner controls don't cover the main control's events?

Blazi
  • 991
  • 3
  • 9
  • 19
  • Its a little bit strange, how would you then trigger the Button click? Why would you then need a button? – Nikola Davidovic Feb 25 '13 at 21:39
  • @NikolaDavidovic Well, you could have one handler for any click within the whole UC and another handler to run when just the button is clicked. You can have more than one handler per event, so nothing is stopping that. – Servy Feb 25 '13 at 21:46
  • @Servy True but I expected the answer from the OP, that way he would clarify the question and we could offer the better answer. – Nikola Davidovic Feb 25 '13 at 21:51
  • @Nikola hi, this is just an example. we can say a picturebox and a label or something.. a control which has an icon beside it for example. – Blazi Feb 25 '13 at 21:58
  • @Blazi Well in that case I can't think of a better way than to assign the same Click handler to all controls' Click events. – Nikola Davidovic Feb 25 '13 at 22:00

2 Answers2

2

I'd suggest leveraging the UserControls Load event to iterate over all sub controls in your project and add a handler programmatically for each MouseMoved event. This would be robust enough to handle any new sub controls added. E.g;

    private void UserControl1_Load(object sender, EventArgs e)
    {
        foreach (Control c in Controls)
        {
            c.MouseMove += Control_Move;
        }
    }

    protected void Control_Move(object sender, MouseEventArgs e)
    {
        // do stuff here
    }

And don't forget to hook your UserControl's MouseMove event to the same Control_Move method

DiskJunky
  • 4,750
  • 3
  • 37
  • 66
  • That's only true if each child control does the same, which they may not do. – Servy Feb 25 '13 at 21:41
  • @Servy true... The only other way I can think if is delving into the Win32 api and adding message hooks. If .NET doesn't expose the necessary event then there's nothing else you can do except effectively create your own – DiskJunky Feb 25 '13 at 21:45
  • @DiskJunky thanks, so I should add every event, `MouseMove` `MouseClick` `Load`,... one by one, this way? – Blazi Feb 25 '13 at 22:03
  • @Blazi every event you want to handle anyway. What are you trying to do exactly? – DiskJunky Feb 25 '13 at 22:05
2

I did something like this in Delphi. The trick was to not add a label, but add a sub class of a label, button, etc, that calls the parents events on the event.

The sub class just overrides Click, Move etc and calls parent. Simple, and saves lots of time if you have a lot of these.

CharlesW
  • 625
  • 6
  • 14
  • Can you please explain more how can I override an event? – Blazi Feb 26 '13 at 07:27
  • class ParentUserControl : UserControl { public override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); } } //Your new control derives from this............ class ParentClickButton : Button { protected override void OnMouseDown(MouseEventArgs mevent) { ((ParentUserControl)this.Parent).OnMouseDown(mevent); base.OnMouseDown(mevent); } } //You new control adds these instead of buttons... – CharlesW Feb 26 '13 at 15:52
  • Also, look at this post for another method I've used before: http://stackoverflow.com/questions/547172/pass-through-mouse-events-to-parent-control – CharlesW Feb 26 '13 at 15:52