How to iterate over contained controls to set a common event handler (Click) in .NET

The requirement was to assign a click event handler to all Label Controls contained in a .NET User Control.  This is a simple technique but I found there was no good documentation on how to do this. 

To illustrate how to do this, I created a simple Windows Form application in C# and added a new Windows Forms User Control to the project.  I called it AutoLabelClickControl.  I placed a label right on the control called ‘Control Label’.  I added a panel with a label on it called ‘Panel Label’ and then placed a panel contained in the first panel and put a label on it called ‘Panel in a Panel Label’.

image

The idea now is that when the control ‘AutoLabelClickControl’ is loaded, code should hook up a common click event handler for all labels.  Add a _Load event handler to your Control (not the Form) using the wizard and let’s add the necessary code:

// This is the Common Event Handler for all Label Clicks
private void LabelClickEventHandler(object sender, EventArgs e)
{
    // Ensure we can typecast correctly!
    if (sender is Label)
    {
        // Do whatever you want... in this case show the Name of the control clicked
        Label aLabel = sender as Label;
        MessageBox.Show(aLabel.Name);
    }

}

// Walk the collection recursively and find Label Controls and wire them up
private void FindLabelControlsInContainerAndAssignEvent(Control.ControlCollection aCollection)
{
    foreach (Control aControl in aCollection)
    {
        // does this control contain other controls?
        if (aControl.Controls.Count > 0)
        {
            // call this function recursively!
            FindLabelControlsInContainerAndAssignEvent(aControl.Controls);
        }

        // wire up our Common Event Handler
        if (aControl is System.Windows.Forms.Label)
        {
            aControl.Click += new System.EventHandler(LabelClickEventHandler);
        }

    }
}

private void AutoLabelClickControl_Load(object sender, EventArgs e)
{
    // When loading wire up the events for all contained Labels
    FindLabelControlsInContainerAndAssignEvent(this.Controls);
}

 

And here is the test!

image

Note:  Although you may think you cannot have a label contained in a label control, you can actually do this if you edit the Designer code (not recommended) and that is why I did not have an ‘else’ statement between these:

// does this control contain other controls?
        if (aControl.Controls.Count > 0)
        {
            // call this function recursively!
            FindLabelControlsInContainerAndAssignEvent(aControl.Controls);
        }

// LOOK – NO ELSE STATEMENT… IN THEORY A LABEL COULD CONTAIN A LABEL BUT YOU WOULD HAVE TO HACK IT IN

        // wire up our Common Event Handler
        if (aControl is System.Windows.Forms.Label)
        {
            aControl.Click += new System.EventHandler(LabelClickEventHandler);
        }

It would be EXTREMELY weird for someone to do this but…  I have been around a while so that is why I wrote that code that way :-)

Note:  It is up to you to apply proper error checking and try/catch blocks to this code.  See the terms of use in my Blog header.

 

Please drop me a note if you find this useful!