Pass Parameter to Eventhandler

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);

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.

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));

Trying to pass a parameter to a new EventHandler

The EventHandler<CoreWebView2NavigationCompletedEventArgs> delegate has signature that delares a parameter sender of type object and e of type CoreWebView2NavigationCompletedEventArgs.

public delegate void EventHandler<CoreWebView2NavigationCompletedEventArgs>(object sender, CoreWebView2NavigationCompletedEventArgs e);

However, the lambda expression e => InputText(this, e, "Test") has only one parameter e. You need to add a second parameter for sender to match the delegate signature above. Let's call it s.

(s, e) => InputText(this, e, "Test")

If you do not use the parameter anyway, you can also ignore it explicitly with the discard operator.

(_, e) => InputText(this, e, "Test")

Please also make sure that your test parameter is used in your method. Here I use string interpolation with $ to insert the value of test into your script.

private async void InputText(object sender, CoreWebView2NavigationCompletedEventArgs args, string test)
{
await webView.ExecuteScriptAsync($"document.getElementById('Textbox').value = '{test}';");
}

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)
}

How can I pass EventHandler as a method parameter

Just use the type of the event handler as argument type:

public static void BuildPaging(Control pagingControl
, short currentPage
, short totalPages
, EventHandler eh // <- this one
)
{
for (int i = 0; i < totalPages; i++)
{
LinkButton pageLink = new LinkButton();
...
pageLink.Click += eh;
pagingControl.Controls.Add(paheLink);
}
}

Note: Don't forget to remove the event handler when done or you might leak memory!

C# pass parameters to event handler

If you are the person writing the code that's raising the event, Mr. Hopkinson puts it very nicely in his answer. You need a custom EventArgs with properties to represent the data you hope to pass.

But if you are merely consuming the event rather than raising it, your options are more limited.

Since you're anticipating receiving an AsyncCompletedEventArgs from your event, though, you do have one option: the UserState propery of AsyncCompletedEventArgs. This is a property you get to supply when you call the asynchronous method that ultimately causes the event to be fired. It can be any object you choose. You supply it when you call the async method, and the event returns it to you in the event argument properties when the method call completes.

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!!!
}

How to use / pass parameters to event handlers?

The method must have parameters matching the Control.Click event delegate, which in this case is EventHandler. Therefore, clicked method needs an Object type parameter followed by EventArgs type parameter.

The first parameter represents the object for which the event occured. Therefore, upon casting it within the handler you will be able to get any of its properties, including Name:

Public Sub clicked(sender As Object, e As EventArgs)
MessageBox.Show("You clicked on button " & CType(sender, Control).Name)
End Sub

EDIT:

In the comments, you ask if it's possible to pass extra parameters to event handler methods. To that, the short answer is that you shouldn't rely on that possibility - especially for events defined outside your codebase.

NOTE: For your own, self-defined events, this is easy: you do your own EventArgs-derived type and put whatever you want in there.

There are ways around this, though. You could store values within class scope and access them in the handler. You could create a dictionary of values whose keys would be something that uniquely identifies your buttons.

A less elegant method would be to store information in each Button's Tag property. Since the handler always have an Object parameter representing the object raising the event, you can retrieve any of its properties within its context.

For example, when you create a new Button instance, you can set its Tag property to the cbutton value from which it is being created:

Public Sub writeButtons()
' ...

Dim cmbDynamic As New Button()
' ...
cmbDynamic.Tag = item

' ...
End Sub

So, later on, you'll be able to recover the full cbutton value simply by doing this:

Public Sub clicked(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim item As cbutton = btn.Tag

MessageBox.Show("You clicked on button " & item.getname() & " which has cbutton.anyproperty equals to " & item.anyproperty)


End Sub

You can think of Tag property as freestyle storage.

Word of advise though: do not abuse of it. The more you use it, the harder your code will be to figure out. Plus, you might end up having unexpected values in these should you have more than one mechanic that uses them.

ADDITIONAL NOTE:

As per .NET conventions, the preferred casing for types and type members is for every words to start with a capital letter. For example, writeButtons really should be WriteButtons. I should also mention that methods starting with Write suggests I/O operations happening. In your case, CreateButtons sounds more appropriate.



Related Topics



Leave a reply



Submit