Pass extra parameters to an event handler?

Let's say I want to pass some extra data when assigning an event handler. Consider the following code:

private void setup(string someData)
{
     Object.assignHandler(evHandler);
}

public void evHandler(Object sender)
{
    // need someData here!!!
}

How would I go about getting someData into my evHandler method?


private void setup(string someData)
{
     Object.assignHandler((sender) => evHandler(sender,someData));
}
public void evHandler(Object sender, string someData)
{
    // need someData here!!!
}

I had a hard time figuring out @spender's example above especially with: Object.assignHandler((sender) => evHandler(sender,someData)); because there's no such thing as Object.assignHandler in the literal sense. So I did a little more Googling and found this example. The answer by Peter Duniho was the one that clicked in my head (this is not my work):

snip

The usual approach is to use an anonymous method with an event handler that has your modified signature. For example:

void Onbutton_click(object sender, EventArgs e, int i) { ... }

button.Click += delegate(object sender, EventArgs e) 
{ Onbutton_click(sender, e, 172); };

Of course, you don't have to pass in 172, or even make the third parameter an int. :)

/snip

Using that example I was able to pass in two custom ComboBoxItem objects to a Timer.Elapsed event using lambda notation:

simulatorTimer.Elapsed +=
(sender, e) => onTimedEvent(sender, e,
(ComboBoxItem) cbPressureSetting.SelectedItem,
(ComboBoxItem) cbTemperatureSetting.SelectedItem);

and then into it's handler:

static void onTimedEvent(object sender, EventArgs e, ComboBoxItem pressure, ComboBoxItem temperature)
    {
        Console.WriteLine("Requested pressure: {0} PSIA\nRequested temperature: {1}° C", pressure, temperature);
    }

This isn't any new code from the examples above, but it does demonstrate how to interpret them. Hopefully someone like me finds it instructive & useful so they don't spend hours trying to understand the concept like I did.

This code works in my project (except for a non-thread-safe exception with the ComboBoxItem objects that I don't believe changes how the example works). I'm figuring that out now.


Captured variables:

private void setup(string someData)
{
    Object.assignHandler((sender,args) => {
        evHandler(sender, someData);
    });
}

public void evHandler(Object sender, string someData)
{
    // use someData here
}

Or (C# 2.0 alternative):

    Object.assignHandler((EventHandler)delegate(object sender,EventArgs args) {
        evHandler(sender, someData);
    });