WinForm Label Not Getting Focus

I have a user control that contains a few other controls, including Labels.  When any of the controls gets focus I want the parent to get notified.  I added an Enter event handler to the parent.  (Note: with Forms the equivalent to Enter/Leave is Activate/Deactivate.)  This almost works – any time I click on anything *except* the Labels the parent control gets focus.  After a bit of research I realized my error – Labels cannot receive focus, therefore the Enter event never fires despite it being there due to deriving from the Control class. (Enter and Leave events travel up the tree so all parents controls get notified.)

Stepping back, what I really want is that when I click anywhere on the control an Enter event is fired.

Since my control will mostly be used via the mouse my solution was to add a MouseClick handler for each label that simply sets the focus on the parent:

private void label1_MouseClick(object sender,
                               MouseEventArgs e)
{
    this.Focus();
}

This worked for my purposes.  But it required overriding the event handler for every label on the form which generated a lot of fluff since they’re all identical.  So the next step was to point them all to the same event handler:

private void LabelSetParentFocus_MouseClick(
                               object sender,
                               MouseEventArgs e)
{
    this.Focus();
}

This was an improvement, but we can do better.  So I deleted all of the event handlers and added the following to the constructor after the InitalizeComponent():

MouseEventHandler handler = new
    System.Windows.Forms.MouseEventHandler(
        this.LabelSetParentFocus_MouseClick);

foreach(Control ctrl in this.Controls)
{
    if (ctrl is Label)
    {
        ctrl.MouseClick += handler;
    }
}

Now we’re dynamically adding a MouseClick handler to every label on the control.

This is more dynamic and usable, but we can still do better by replacing LabelSetParentFocus_MouseClick with an anonymous function (aka lamdba expression):

MouseEventHandler handler = (sender, e) =>
    {
        this.Focus();
    };

foreach(Control ctrl in this.Controls)
{
    if (ctrl is Label)
    {
        ctrl.MouseClick += handler;
    }
}

Good.  With just one more tweak we have a much more elegant cut and paste solution:

foreach(Control ctrl in this.Controls)
{
    if (ctrl is Label)
    {
        ctrl.MouseClick += (sender, e) => this.Focus();
    }
}

We don’t have to worry about adding the handler to any new labels that we add later and I expect this functionality will carry through onto derived child classes as well.

This can easily be customized to other scenarios and events.

Cheers.