Understanding Events and Event Handlers in C#

Understanding events and event handlers in C#

To understand event handlers, you need to understand delegates. In C#, you can think of a delegate as a pointer (or a reference) to a method. This is useful because the pointer can be passed around as a value.

The central concept of a delegate is its signature, or shape. That is (1) the return type and (2) the input arguments. For example, if we create a delegate void MyDelegate(object sender, EventArgs e), it can only point to methods which return void, and take an object and EventArgs. Kind of like a square hole and a square peg. So we say these methods have the same signature, or shape, as the delegate.

So knowing how to create a reference to a method, let's think about the purpose of events: we want to cause some code to be executed when something happens elsewhere in the system - or "handle the event". To do this, we create specific methods for the code we want to be executed. The glue between the event and the methods to be executed are the delegates. The event must internally store a "list" of pointers to the methods to call when the event is raised.* Of course, to be able to call a method, we need to know what arguments to pass to it! We use the delegate as the "contract" between the event and all the specific methods that will be called.

So the default EventHandler (and many like it) represents a specific shape of method (again, void/object-EventArgs). When you declare an event, you are saying which shape of method (EventHandler) that event will invoke, by specifying a delegate:

//This delegate can be used to point to methods
//which return void and take a string.
public delegate void MyEventHandler(string foo);

//This event can cause any method which conforms
//to MyEventHandler to be called.
public event MyEventHandler SomethingHappened;

//Here is some code I want to be executed
//when SomethingHappened fires.
void HandleSomethingHappened(string foo)
{
//Do some stuff
}

//I am creating a delegate (pointer) to HandleSomethingHappened
//and adding it to SomethingHappened's list of "Event Handlers".
myObj.SomethingHappened += new MyEventHandler(HandleSomethingHappened);

//To raise the event within a method.
SomethingHappened("bar");

(*This is the key to events in .NET and peels away the "magic" - an event is really, under the covers, just a list of methods of the same "shape". The list is stored where the event lives. When the event is "raised", it's really just "go through this list of methods and call each one, using these values as the parameters". Assigning an event handler is just a prettier, easier way of adding your method to this list of methods to be called).

Understanding C# Event Handler: why no event?

You want to create a method that handles the event in SemesterView and tie the event to the handler:

class SemesterView : DataGridView
{
public void MyEvent(object sender, EventArgs args)
{

}
}

Then in Form1

SemesterView semesterView;
semesterView = new SemesterView();
this.Controls.Add(semesterView);
semesterView.Enter += semesterView.MyEvent;

Need help understanding Events in C#

the OnOneSecond method will be called internally by the MyTimerClass when it needs to invoke the event.

This is a common pattern used by most controls, including the microsoft ones.

Basically you dont need to be checking if the event is set in multiple places, you just do it in this one method then call this method internally to raise the event.

I tend not to pass the event args to the OnXXX method though, for example.

public event EventHandler<EventArgs> SomeEvent;
protected virtual void OnSomeEvent()
{
if (this.SomeEvent !=null)
{
this.SomeEvent.Invoke(this,EventArgs.Empty);
}
}

then to raise it

this.OnSomeEvent();

Help understanding .NET delegates, events, and eventhandlers

I would start with these:

http://www.yoda.arachsys.com/csharp/events.html

http://msdn.microsoft.com/en-us/library/ms173171.aspx

Event handling, how to chain events

You can add eventhandlers yourself.

var m = new Metronome();
m.Tick += (s, e) => {
Console.WriteLine("Processed initial event");
};
var l = new Listener();
l.Subscribe(m);
m.Tick += (s, e) => {
Console.WriteLine("Processed the final event");
};
m.Start();

This should give you the wanted result. Keep in mind that to order in which you add the events is the order that they are executed in.

Or, if you want multiple listeners:

public class Listener {
private string _msg;
public Listener (string msg) {
_msg = msg;
}

public void Subscribe(Metronome m) {
m.Tick += new Metronome.TickHandler(HeardIt);
}

private void HeardIt(Metronome m, EventArgs e) {
Console.WriteLine(msg);
}
}

var m = new Metronome();
new Listener("Processed initial event").Subscribe(m);
new Listener("Ticked").Subscribe(m);
new Listener("Processed the final event").Subscribe(m);
m.Start();

what role event delegates play?

This can help you to understand events and delegates:

Events in .NET are based on the delegate model. The delegate model follows the observer design pattern, which enables a subscriber to register with and receive notifications from a provider. An event sender pushes a notification that an event has happened, and an event receiver receives that notification and defines a response to it. This article describes the major components of the delegate model, how to consume events in applications, and how to implement events in your code.

An event is a message sent by an object to signal the occurrence of an action. The action can be caused by user interaction, such as a button click, or it can result from some other program logic, such as changing a property’s value. The object that raises the event is called the event sender. The event sender doesn't know which object or method will receive (handle) the events it raises. The event is typically a member of the event sender; for example, the Click event is a member of the Button class, and the PropertyChanged event is a member of the class that implements the INotifyPropertyChanged interface.

To define an event, you use the C# event or the Visual Basic Event keyword in the signature of your event class, and specify the type of delegate for the event. Delegates are described in the next section.

Typically, to raise an event, you add a method that is marked as protected and virtual (in C#) or Protected and Overridable (in Visual Basic). Name this method OnEventName; for example, OnDataReceived. The method should take one parameter that specifies an event data object, which is an object of type EventArgs or a derived type. You provide this method to enable derived classes to override the logic for raising the event. A derived class should always call the OnEventName method of the base class to ensure that registered delegates receive the event.

A simple example is the Button control: when you click on it, the event OnClick is raised and the control call all delegates that have suscribed to it using:

Click += SomeMethod;

Or (it is the same):

Click += new EventHandler(SomeMethod);

If fact, it adds a reference to the method in the event handler list.

An event is just a list of methods to call in case of the event is raised, like with the button click.

A delegate is just a signature of a method without a body implementation, also called a prototype, to be used as a type, to have strong typing when adding events to an event handler like the button click. So when you assign a method implemented, by its name, it must match the delegate signature (return type and parameters, the name of the delegate itself is not pertinent except for humans).

We also can use lambda:

myButton1.Click += (sender, e) => Close();

myButton2.Click += (sender, e) => { MessageBox.Show("Closing"); Close() };

Handling and raising events (MS Docs)

C# - Events(TutorialsPoint)

C# - Events (TutorialsTeacher)

What are C# Events? (YouTube)

C# Tutorial: Events/Event Handlers (YouTube)

Event handlers in Visual Studio

There is a Form.Designer.cs file that hooks up the events for each individual form (each form has it's own designer file).

Open that and you'll find lines like:

button1.Click += button1_Click;

..etc.

As below:

Designer file

Click wiring

Add and remove async event handlers using reflection in c#

This should work:

var obj = new InstrumentInstance("foo");

EventCompletedHandler handler = async (s, e) => await ProcessInstrumentEvent(s, e);

foreach (var evt in obj.GetType().GetEvents(BindingFlags.Public | BindingFlags.Instance))
{
if (evt.EventHandlerType == typeof(EventCompletedHandler))
{
Console.WriteLine($"Binding '{evt.Name}'");
evt.AddEventHandler(obj, handler);
}
}

It should also work without the extra indirection:

EventCompletedHandler handler = ProcessInstrumentEvent;


Related Topics



Leave a reply



Submit