Search code examples
c#winformsevent-handlinggeneric-handler

Hooking up generic event handlers to multiple controls of the same type


I have a WinForms app that contains many NumericUpDown controls. In a nutshell, if my users enter a value into the control and then delete the text, I want to restore it (the text) when the control loses focus. So I decided that I'd check .Text when the control loses focus and if it's empty, I set .Text = .Value.ToString().

I'm doing this in the Leave event handler and it works just fine. But as I said, I have many of these controls (18, to be exact). I don't like creating 18 Leave event handlers that all do the same thing so I created a generic one like this:

private void numericUpDown_GenericLeave(object sender, EventArgs e)
{
    if (string.IsNullOrEmpty(((NumericUpDown)sender).Text))
        ((NumericUpDown)sender).Text = ((NumericUpDown)sender).Value.ToString();
}

I started to hook up all of the controls to this generic event handler but I quickly got tired of doing this:

numericUpDown1.Leave += numericUpDown_GenericLeave;
numericUpDown2.Leave += numericUpDown_GenericLeave;
numericUpDown3.Leave += numericUpDown_GenericLeave;
...
numericUpDown18.Leave += numericUpDown_GenericLeave;

So I thought I'd create a function that would return a list of all the controls of a specified type and then loop through that list and hookup the event handlers. That function looks like this:

public static List<Control> GetControlsOfSpecificType(Control container, Type type)
{
    var controls = new List<Control>();

    foreach (Control ctrl in container.Controls)
    {
        if (ctrl.GetType() == type)
            controls.Add(ctrl);

        controls.AddRange(GetControlsOfSpecificType(ctrl, type));
    }

    return controls;
}

I call the function like this:

var listOfControls = GetControlsOfSpecificType(this, typeof(NumericUpDown));

foreach (var numericUpDownControl in listOfControls)
{
    numericUpDownControl.Leave += numericUpDown_GenericLeave;
}

When I run my app, however, I don't see the expected behavior that occurs when I manually hookup each control to the generic event handler. This code is currently in the constructor of my form and I've tried calling it before as well as after the call to InitializeComponent() but neither one seems to be working. I get no error of any kind, I just don't see the behavior that I was expecting. I have a breakpoint set inside the generic event handler but the debugger never breaks so it seems like the event handler isn't being hooked up correctly. Does anyone know why this might be or how I can troubleshoot it further? Thanks!

EDIT

I just realized that the call to:

var listOfControls = GetControlsOfSpecificType(this, typeof(NumericUpDown));

was happening before the call to InitializeComponent() so of course the list of controls being returned was empty. DOH! Thanks for all the replys. I apologize for wasting everyones time. :-(


Solution

  • Question answered. See Edit above. Thanks to bsegraves for pointing me in the right direction.