Consuming Events
To consume an event in an application, you must provide an event handler (an event-handling method) that executes program logic in response to the event and register the event handler with the event source. This process is referred to as event wiring. The visual designers for Windows Forms and Web Forms provide rapid application development (RAD) tools that simplify or hide the details of event wiring.
This topic describes the general pattern of handling events. For an overview of the event model in the .NET Framework, see Events and Delegates. For more information about the event model in Windows Forms, see How to: Consume Events in a Windows Forms Application. For more information about the event model in Web Forms, see How to: Consume Events in a Web Forms Application.
The Event Pattern
The details of event wiring differ in Windows Forms and Web Forms because of the different levels of support provided by different RAD tools. However, both scenarios follow the same event pattern, which has the following characteristics:
- A class that raises an event named EventName has the following member:
Public Event EventName As EventNameEventHandler
public event EventNameEventHandler EventName;
public:
event EventNameEventHandler^ EventName;
- The event delegate for the EventName event is EventNameEventHandler, with the following signature:
Public Delegate Sub EventNameEventHandler(sender As Object, e As EventNameEventArgs)
public delegate void EventNameEventHandler(object sender, EventNameEventArgs e);
delegate void EventNameEventHandler(Object^ sender, EventNameEventArgs^ e);
To consume the EventName event, your event handler must have the same signature as the event delegate:
Sub EventHandler(sender As Object, e As EventNameEventArgs)
End Sub
void EventHandler(object sender, EventNameEventArgs e) {}
void EventHandler(Object^ sender, EventNameEventArgs^ e) {}
Note
An event delegate in the .NET Framework is named EventNameEventHandler, while the term event handler in the documentation refers to an event-handling method. The logic behind the naming scheme is that an EventNameEventHandler delegate points to the event handler (the method) that actually handles the event.
When an event does not have any associated data, the class raising the event uses System.EventHandler as the delegate and System.EventArgs for the event data. Events that have associated data use classes that derive from EventArgs for the event data type, and the corresponding event delegate type. For example, if you want to handle a MouseUp event in a Windows Forms application, the event data class is MouseEventArgs and the event delegate is MouseEventHandler. Note that several mouse events use a common class for event data and a common event delegate, so the naming scheme does not exactly match the convention described above. For the mouse events, your event handler must have the following signature:
Sub Mouse_Moved(sender As Object, e As MouseEventArgs)
End Sub
void Mouse_Moved(object sender, MouseEventArgs e){}
void Mouse_Moved(Object^ sender, MouseEventArgs^ e){}
The sender and event argument parameters supply additional details about the mouse event to the event handler. The sender object indicates what raised the event. The MouseEventArgs parameter provides details on the mouse movement that raised the event. Many event sources provide additional data for the event, and many event handlers use the event-specific data in processing the event. For an example that demonstrates raising and handling events with event-specific data, see How to: Raise and Consume Events.
Note
Events also arise outside the context of user interfaces (UIs), and, in fact, the .NET Framework includes many non-UI classes that raise events. However, all events follow the pattern described here.
For information about raising events from a class, see Raising an Event.
Static and Dynamic Events
The .NET Framework allows subscribers to register for event notifications either statically or dynamically. Static event handlers are in effect for the entire life of the class whose events they handle. This is the most common method of handling events. Dynamic event handlers are explicitly activated and deactivated during program execution, usually in response to some conditional program logic. For example, they can be used if event notifications are needed only under certain conditions or if an application provides multiple event handlers and run-time conditions define the appropriate one to use.
The EventInfo.AddEventHandler method adds dynamic event handlers and the EventInfo.RemoveEventHandler method deactivates them. Individual languages also provide their own features for handling events dynamically. The following example defines a TemperatureMonitor class that raises a TemperatureTheshold event whenever the temperature reaches a predefined threshold. An event handler that subscribes to this event is then activated and deactivated during program execution.
public class TemperatureEventArgs : Inherits EventArgs
Private oldTemp As Decimal
Private newTemp As Decimal
Public ReadOnly Property OldTemperature As Decimal
Get
Return Me.oldTemp
End Get
End Property
Public ReadOnly Property NewTemperature As Decimal
Get
Return Me.newTemp
End Get
End Property
Public Sub New(oldTemp As Decimal, newTemp As Decimal)
Me.oldTemp = oldTemp
Me.newTemp = newTemp
End Sub
End Class
Public Delegate Sub TemperatureEventHandler(sender As Object, _
ev As TemperatureEventArgs)
Public Class TemperatureMonitor
Private currentTemperature As Decimal
Private threshholdTemperature As Decimal
Public Event TemperatureThreshold As TemperatureEventHandler
Public Sub New(threshHold As Decimal)
Me.threshholdTemperature = threshHold
End Sub
Public Sub SetTemperature(newTemperature As Decimal)
If (Me.currentTemperature > threshholdTemperature And _
newTemperature <= Me.threshholdTemperature) Or _
(Me.CurrentTemperature < Me.threshholdTemperature And _
newTemperature >= Me.threshholdTemperature) Then
OnRaiseTemperatureEvent(newTemperature)
End If
Me.currentTemperature = newTemperature
End Sub
Public Function GetTemperature() As Decimal
Return Me.currentTemperature
End Function
Protected Overridable Sub OnRaiseTemperatureEvent(newTemperature As Decimal)
RaiseEvent TemperatureThreshold(Me, New TemperatureEventArgs(Me.currentTemperature, _
newTemperature))
End Sub
End Class
Public Module Example
Public Sub Main()
Dim tempMon As New TemperatureMonitor(32d)
tempMon.SetTemperature(33)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
tempMon.SetTemperature(32)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
' Add event handler dynamically using Visual Basic syntax.
AddHandler tempMon.TemperatureThreshold, AddressOf TempMonitor
tempMon.SetTemperature(33)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
tempMon.SetTemperature(34)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
tempMon.SetTemperature(32)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
' Remove event handler dynamically using Visual Basic syntax.
RemoveHandler tempMon.TemperatureThreshold, AddressOf TempMonitor
tempMon.SetTemperature(31)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
tempMon.SetTemperature(35)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
End Sub
Private Sub TempMonitor(sender As Object, e As TemperatureEventArgs)
Console.WriteLine(" ***Warning: Temperature is changing from {0} to {1}.", _
e.OldTemperature, e.NewTemperature)
End Sub
End Module
' The example displays the following output:
' Current temperature is 33 degrees Fahrenheit.
' Current temperature is 32 degrees Fahrenheit.
' Current temperature is 33 degrees Fahrenheit.
' Current temperature is 34 degrees Fahrenheit.
' ***Warning: Temperature is changing from 34 to 32.
' Current temperature is 32 degrees Fahrenheit.
' Current temperature is 31 degrees Fahrenheit.
' Current temperature is 35 degrees Fahrenheit.
using System;
public class TemperatureEventArgs : EventArgs
{
private decimal oldTemp;
private decimal newTemp;
public decimal OldTemperature
{
get { return this.oldTemp; }
}
public decimal NewTemperature
{
get { return this.newTemp; }
}
public TemperatureEventArgs(decimal oldTemp, decimal newTemp)
{
this.oldTemp = oldTemp;
this.newTemp = newTemp;
}
}
public delegate void TemperatureEventHandler(object sender, TemperatureEventArgs ev);
public class TemperatureMonitor
{
private decimal currentTemperature;
private decimal threshholdTemperature;
public event TemperatureEventHandler TemperatureThreshold;
public TemperatureMonitor(decimal threshhold)
{
this.threshholdTemperature = threshhold;
}
public void SetTemperature(decimal newTemperature)
{
if ( (this.currentTemperature > this.threshholdTemperature &&
newTemperature <= this.threshholdTemperature) ||
(this.currentTemperature < this.threshholdTemperature &&
newTemperature >= this.threshholdTemperature) )
OnRaiseTemperatureEvent(newTemperature);
this.currentTemperature = newTemperature;
}
public decimal GetTemperature()
{
return this.currentTemperature;
}
protected virtual void OnRaiseTemperatureEvent(decimal newTemperature)
{
// Raise the event if it has subscribers.
if (TemperatureThreshold != null)
TemperatureThreshold(this, new TemperatureEventArgs(this.currentTemperature,
newTemperature));
}
}
public class Example
{
public static void Main()
{
Example ex = new Example();
ex.MonitorTemperatures();
}
public void MonitorTemperatures()
{
TemperatureMonitor tempMon = new TemperatureMonitor(32);
tempMon.SetTemperature(33);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
tempMon.SetTemperature(32);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
// Add event handler dynamically using C# syntax.
tempMon.TemperatureThreshold += this.TempMonitor;
tempMon.SetTemperature(33);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
tempMon.SetTemperature(34);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
tempMon.SetTemperature(32);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
// Remove event handler dynamically using C# syntax.
tempMon.TemperatureThreshold -= this.TempMonitor;
tempMon.SetTemperature(31);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
tempMon.SetTemperature(35);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
}
private void TempMonitor(object sender, TemperatureEventArgs e)
{
Console.WriteLine(" ***Warning: Temperature is changing from {0} to {1}.",
e.OldTemperature, e.NewTemperature);
}
}
// The example displays the following output:
// Current temperature is 33 degrees Fahrenheit.
// Current temperature is 32 degrees Fahrenheit.
// Current temperature is 33 degrees Fahrenheit.
// Current temperature is 34 degrees Fahrenheit.
// ***Warning: Temperature is changing from 34 to 32.
// Current temperature is 32 degrees Fahrenheit.
// Current temperature is 31 degrees Fahrenheit.
// Current temperature is 35 degrees Fahrenheit.
See Also
Tasks
How to: Consume Events in a Web Forms Application
How to: Consume Events in a Windows Forms Application