6

I have different controls in my usercontrols. And load usercontrols dynamically in my form

UserControl2 usercontrol = new UserControl2();
usercontrol.Tag = i;
usercontrol.Click += usercontrol_Click;
flowLayoutPanel1.Controls.Add(usercontrol);

private void usercontrol_Click(object sender, EventArgs e)
{
   // handle event
}

The click event is not firing when I click a control in usercontrol. It only fires when I click on empty area of usercontrol.

Karlx Swanovski
  • 2,869
  • 9
  • 34
  • 67

5 Answers5

17

Recurse through all the controls and wire up the Click() event of each to the same handler. From there call InvokeOnClick(). Now clicking on anything will fire the Click() event of the main UserControl:

public partial class UserControl2 : UserControl
{

    public UserControl2()
    {
        InitializeComponent();
        WireAllControls(this);
    }

    private void WireAllControls(Control cont)
    {
        foreach (Control ctl in cont.Controls)
        {
            ctl.Click += ctl_Click;
            if (ctl.HasChildren)
            {
                WireAllControls(ctl);
            }
        }
    }

    private void ctl_Click(object sender, EventArgs e)
    {
        this.InvokeOnClick(this, EventArgs.Empty); 
    }

}
Idle_Mind
  • 38,363
  • 3
  • 29
  • 40
  • 1
    And the reason for that is? Why is the event not naturally fired? – flaudre Jul 19 '15 at 13:36
  • 2
    @Flaudre, because the child controls all have their own click event that fires. Here we're telling those click handlers to raise the click event for the main usercontrol so that (presumably) the container/parent of the main usercontrol can do something. This would make it seem like the usercontrol is all one "clickable unit". You wouldn't want that, however, if clicking on the individual controls should do something different. – Idle_Mind Jul 19 '15 at 15:38
  • @Idle_Mind thanks, actually it's so obvious after thinking it over twice. – flaudre Jul 20 '15 at 05:47
  • this is pretty slow when you have a lot of controls – andypopa Sep 16 '15 at 13:17
  • 1
    @andypopa, it only wires them up **once**, though, when the UserControl is instantiated. How many controls have you got that you can notice this is "slow"?!...and what is your alternative answer? – Idle_Mind Sep 16 '15 at 14:02
  • 1
    1000+. I have a custom control with 20+ controls inside it (it needs to represent a contact: there's a label for FirstName, a label to contain the actual value for FirstName and so on). I'm creating this control for every database entry. my alternative answer is not that your method is wrong, I think I/everyone else who has this problem (of performance) is doing it wrong. I understand that in this case one should just draw the things instead of adding controls to a usercontrol. EDIT: and if you have a better solution for me I'm also listening :D – andypopa Sep 16 '15 at 14:12
  • 1
    @andypopa, Ignoring the "too many controls" issue, if you do not need to trap mouse events for your labels, **Inherit** from class `Label` and return `HTTRANSPARENT` for the `WM_NCHITTEST` message in `WndProc()`. Now the mouse will "pass through" the Labels and **hit the Parent Container (the UserControl)**. You'd have to change up your UserControl to use the Label control instead of the original. This could be done by directly editing the designer file. See this [SO answer](http://stackoverflow.com/questions/547172/pass-through-mouse-events-to-parent-control/8635626#8635626) for details. – Idle_Mind Sep 16 '15 at 14:30
1

This should solve your problem.

//Event Handler for dynamic controls
usercontrol.Click += new EventHandler(usercontrol_Click); 
Chris Stillwell
  • 10,266
  • 10
  • 67
  • 77
Apollo
  • 1,990
  • 12
  • 44
  • 65
0

Take this:

this.btnApply.Click += new System.EventHandler(this.btnApply_Click);

icbytes
  • 1,831
  • 1
  • 17
  • 27
0

Because events from ChildControls are not propagated to parents. So you have to handle Click event on every child control added to UserControl.

gzaxx
  • 17,312
  • 2
  • 36
  • 54
0

1-define a delegate at nameapace

public delegate void NavigationClick(int Code, string Title);

2-define a event from your delegate in UserControl class:

        public  event NavigationClick navigationClick;

3-write this code for your control event in UserControl:

private void btn_first_Click(object sender, EventArgs e)
    {
        navigationClick(101, "First");
    }

4-in your Windows Form than use from your UserControl at Event add:

private void dataBaseNavigation1_navigationClick(int Code, string Title)
    {
        MessageBox.Show(Code + " " + Title);
    }
JAvAd
  • 114
  • 1
  • 9