Pass Extra Parameters to an Event Handler

Pass parameter to EventHandler

Timer.Elapsed expects method of specific signature (with arguments object and EventArgs). If you want to use your PlayMusicEvent method with additional argument evaluated during event registration, you can use lambda expression as an adapter:

myTimer.Elapsed += new ElapsedEventHandler((sender, e) => PlayMusicEvent(sender, e, musicNote));

Edit: you can also use shorter version:

myTimer.Elapsed += (sender, e) => PlayMusicEvent(sender, e, musicNote);

Pass extra parameters to an event handler?


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

C# pass additional parameter to an event handler while binding the event at the run time

You can use anonymous delegate for that:

lnkSynEvent.Click += 
new EventHandler((s,e)=>lnkSynEvent_Click(s, e, your_parameter));

passing extra parameter to event handler

You can use the .bind method and the arguments object inside the function to access extra parameters you want to pass in

$(function(){
$('#btn').click(function(){

var id = $(this).attr('id');

util.doSomething({
property1: "SomeValue1",
property2: "SomeValue2",
onDone: update.bind(this, id)
})
})

function update()
{
console.log(arguments); // inside arguments you should see all your parameters
// arguments[0] your id
// arguments[1] your response
}
})

Pass additional parameters or objects using an Event Handler

Yes you can extend your DataReceivedArgs to DataReceivedArgsExtended, but remeber cast it into event handler method. For example:

public class MyObject
{
public event EventHandler<MyEventArgs> OnFire;

public void Fire()
{
if( OnFire != null )
{
//var e = new MyEventArgs { X=2 };

var e = new MyEventArgsNew { X = 3, Y = 4 };

OnFire( this, e );
}
}
}

public class MyEventArgs : EventArgs
{
public int X { get; set; }
}

public class MyEventArgsNew : MyEventArgs
{
public int Y { get; set; }
}

static void Main( string[] args )
{
var obj = new MyObject();

obj.OnFire += new EventHandler<MyEventArgs>( obj_OnFire );

obj.Fire();

Console.ReadLine();
}

static void obj_OnFire( object sender, MyEventArgs e )
{
var e2 = (MyEventArgsNew)e;

Console.WriteLine( e2.X );
Console.WriteLine( e2.Y );
}

How to pass extra parameter to event handling callback?

The difference between bind and call/apply is that bind doesn't call the function immediately much like it loads the data with the variable when needed

You can reformat your code so it looks like this

$('#list-button').on('click', postListing.bind(this, url));

Passing parameters to the Event handler

Your problem is in the following line:

Tile[rowNumber, colNumber].Click += new EventHandler((sender,e) => LoadImage_Click(sender, e, rowNumber, colNumber));

You are using a lambda expression that passes rowNumber & colNumber.
When the Click event for the tile is triggered, the lambda is executed and passes the values rowNumber & colNumber have at that time (and not the values they had when the event-handler was created). because your loop have run to completion, the value for colNumber you pass will always be 3.

So you need another mechanism to calculate the row & column for the clicked Tile.
You could do that bases on the sender that is passed: cast it to a Tile, retrieve its position & calculate row & column from that.

If you really want to pass the actual column-number, you could always 'capture the value for 'colNumber' like this:

Tile = new MyPictureBox[rowCount, columnCount];
for (int colNumber = 0; colNumber < columnCount; colNumber++)
{
int actualColumn = colNumber;
int actualRow = rowNumber;

Tile[rowNumber, colNumber] = new MyPictureBox();
...
Tile[rowNumber, colNumber].Click += new EventHandler((sender,e) => LoadImage_Click(sender, e, actualRow, actualColumn));
this.Controls.Add(Tile[rowNumber, colNumber]);

leftPosition += width;
}

For each iteration of the loop where you create your tiles, you create an new variable that contains the actual Row & Column for your tile. Those values will not change, because every iteration has its own version of them. And you pass those variables instead of rowNumber & colNumber.

passing parameter to an event handler

Make a new EventArgs class such as:

    public class ListEventArgs : EventArgs
{
public List<string> Data { get; set; }
public ListEventArgs(List<string> data)
{
Data = data;
}
}

And make your event as this:

    public event EventHandler<ListEventArgs> NewFileAdded;

Add a firing method:

protected void OnNewFileAdded(List<string> data)
{
var localCopy = NewFileAdded;
if (localCopy != null)
{
localCopy(this, new ListEventArgs(data));
}
}

And when you want to handle this event:

myObj.NewFileAdded += new EventHandler<ListEventArgs>(myObj_NewFileAdded);

The handler method would appear like this:

public void myObj_NewFileAdded(object sender, ListEventArgs e)
{
// Do what you want with e.Data (It is a List of string)
}

Passing extra parameters to an event handler?

You could derive from the Ping and then pass your argument in the Pings constructor. Then you have all the freedom to change the behavior of the event and you can alter it to your needs.

I made a simple class from which you can begin with

class ExtendedPing : Ping
{
public delegate void ExtendedPing_Completed(object sender, PingCompletedEventArgs e, int identifier);
public event ExtendedPing_Completed On_ExtendedPing_Completed;

private int _i = 0;

public ExtendedPing(int i)
{
_i = i;
base.PingCompleted += ExtendedPing_PingCompleted;
}

void ExtendedPing_PingCompleted(object sender, PingCompletedEventArgs e)
{
if (On_ExtendedPing_Completed != null)
{
On_ExtendedPing_Completed(sender, e, _i);
}
}
}

Feel free to read https://msdn.microsoft.com/en-gb/library/ms228387(v=VS.90).aspx a little bit more about inheritence.

Passing multiple arguments and event to event handler using bind()

Any arguments passed to bind() after the first are prepended to the arguments provided to the function when it is created, in this case event. This means that in the resulting bound callback the event will be the last argument the callback receives, rather than the first as is normal if not using bind. this remains unchanged as it is an arrow function.

If you are passing a consistent, known number of arguments in each bind() you can access them directly.

const clickHandler = (arg1, arg2, event) => {
...
}

Otherwise, if the number of bound arguments will vary you can access the event by retrieving the last element from the arguments iterator.

const clickHandler = (...args) => {
const event = args.pop();
...
}