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
Differencebetween a Property and a Variable
How to Read Data from a Zip File Without Having to Unzip the Entire File
Failed to Serialize the Response in Web API
What Is an MVChtmlstring and When Should I Use It
How to Check If Tcpclient Connection Is Closed
Is There Anything Like Asynchronous Blockingcollection<T>
How to Add Claims in ASP.NET Identity
How to Add an Extra Button to the Window's Title Bar
One to One Optional Relationship Using Entity Framework Fluent API
How to Copy Part of an Array to Another Array in C#
Deleting Specific Rows from Datatable
Signing and Verifying Signatures with Rsa C#
Populate Data Table from Data Reader
Windows Shell Extension with C#