ARTICLE

C# Events

Posted by Dhananjay Kumar Articles | C# Language March 14, 2009
This article discusses the basics of events in C# and how to take advantage of events by implementing them in your applications.
Reader Level:

This article discusses the basics of events in C# and how to take advantage of events by implementing them in your applications.

Windows based applications are message based. Application is communicating with windows and windows are communicating with application by using predefined messages.  .Net wraps up the messages with 'EVENTS'. And .Net reacting a particular message by handling events. Events are the message sent by an object to indicate the occurrence of an event.  Event can also be defined as a member that enables an object to provide notification. Events provide a powerful means of inter-process communication.  Events are used for communication between Objects. Communication between Objects is done by events.

Delegates are used as the means of wiring up the event when the message is received by the application.

1.gif

Event Receiver

The event receiver may be

  1. An application 
  2. An Object 
  3. A component

Event receiver gets modified when something happens.

Event Sender

The Event sender may be

  1. An assembly in an application 
  2. An object
  3. System events like Mouse event or keyboard entry.

Event sender's job is to raise the Event. Event sender doesn't know anything about, whom and what the receiver is.  To handle the event, there would be some method inside event receiver.  This Event handler method will get executed each time when event is registered to be raised.

Here DELEGATE comes into action, because Sender has no idea who the receiver will be.

The PROCESS of hooking up the event handler is known as WIRING UP an Event.

A simple example of wiring up is CLICK EVENT.

The EventHandler Delegate

This Delegate is defined in .Net framework.  It is defined in System namespace. All of the events that are defined in .Net framework will use it.

  1. EventHandler cannot return any value, so it should return Void. 
  2. Parameters are Object and EventArgs
  3. The first parameter is an Object that raises the Event. 
  4. The Second parameter is EventArgs.  This contains information about the Event.

Example:

Private void Button_Click(Object sender, EventArgs e)
{
}

Here first parameter is a Button; this could be any button if there are multiple buttons on form.

The Second parameter is EventArags. This mainly contains the property for which Button is used.

Example 1:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace EventExample

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

            // Adding EventHandler to Click event of Buttons

            btn1.Click +=new EventHandler(Button_Click);

            btn2.Click +=new EventHandler(Button_Click);

        }

 

         // Button Click  Method , here signature of this is same as of Eventhandler

        private void Button_Click(Object sender, EventArgs e)

        {

            string str;

            if (sender == btn1)

            {

                 str = btn1.Text;

                MessageBox.Show(str+" Clicked ");

            }

            if (sender == btn2)

            {

                str = btn2.Text;

                MessageBox.Show(str+ " Clicked ");

            }

        }

 

    }

}

In above code 

Step 1: Create a Windows Application

Step 2: Two butttons  are dragged on the form. Name of buttons are btn1 and btn2 .

Step 3: At the Constructor part of Form , Eventhandlers are getting add in Button . += operartor is being used for adding EventHandlers.

Step 4: Button_Click is a method having same signature as of EventHandler.

Output:

When button Scott is clicked, in message Box Scott is displaying. In this case  Button_Click method is called by btn1_click delegate. In Button_Click() method , checking has been done for which Button object is calling the event. Or in other words which button is event sender. Code snippet which is checking the sender is

if (sender == btn1)

            {

                 str = btn1.Text;

                MessageBox.Show(str+" Clicked ");

            }

            if (sender == btn2)

            {

                str = btn2.Text;

                MessageBox.Show(str+ " Clicked ");

            }

2.gif

Publish and Subscribe of Event

  1. In Design pattern, the creator of Control (like Button, List etc) "PUBLISHES" the events to which the button will respond (Such as click). 
  2. Programmer who uses the Button (those who put Button on their Form) may choose to "SUBSCRIBE" to one or more of the Button's event. For example As a programmer any one could choose to subscribe ( or Notify) click event of Button but not Mouse Hover over the Button 
  3. Mechanism of publishing is "Creating a Delegate".
  4. Mechanism of subscribing is to create a "method "with same signature as of delegate. 
  5. The Subscribing method is called the "Event Handler"
  6. In .Net Framework all event handlers return void and take two parameters. The first parameter is "Source" of the event. The Second parameter is object derived from "EventArgs". 
  7. EventArgs is the base class for all event data. Other than its constructor, this class inherits all method from Object class. It contains a public static field named "Empty".  This represents an Event with no state. The EventArgs derived class contains information about the Event.

Publish and Subscribe Example

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

 

 

namespace EventExampleTime

{

    #region infoOfEvent

    public class TimeEvent : EventArgs

    {

        public readonly int Hour;

        public readonly int Minute;

        public readonly int Second;

 

        public TimeEvent(int hour, int minute, int second)

        {

            this.Hour = hour;

            this.Minute = minute;

            this.Second = second;

        }

    }

    #endregion

    #region publishClass

    public class Clock

    {

        private int hour;

        private int minute;

        private int second;

        public delegate void SecondChangeHandlerDelegate(object clock, TimeEvent timeInformation);

        public SecondChangeHandlerDelegate SecondChanged;

        protected virtual void OnSecondChanged(TimeEvent e)

        {

            if (SecondChanged != null)

            {

                SecondChanged(this, e);

            }

        }

 

        public void Run()

        {

            for (; ; )

            {

                Thread.Sleep(10);

                DateTime dt = DateTime.Now;

                if(dt.Second!= second)

                {

                    TimeEvent timeInformation = new TimeEvent(dt.Hour, dt.Minute, dt.Second);

                    OnSecondChanged(timeInformation);

                }

                this.second = dt.Second;

                this.minute = dt.Minute;

                this.hour = dt.Hour;

            }

        }

    }

    

    #endregion

 

#region observerClass

    public class DisplayClock

    {

        public void Subscribe(Clock theClock)

        {

            theClock.SecondChanged += new Clock.SecondChangeHandlerDelegate(timeHasChanged);

        }

        public void timeHasChanged(object theClock, TimeEvent ti)

        {

            Console.WriteLine("Current Time : {0}:{1}:{2}", ti.Hour.ToString(), ti.Minute.ToString(), ti.Second.ToString());

 

        }

    }

 

#endregion

    #region observerClass2

    public class LogCurrentTime

    {

        public void Subscribe(Clock theClock)

        {

            theClock.SecondChanged += new Clock.SecondChangeHandlerDelegate(writelogentry);

        }

        public void writelogentry(object theClock, TimeEvent ti)

        {

            Console.WriteLine(" Logging to File : {0}:{1}:{2}", ti.Hour.ToString(), ti.Minute.ToString(), ti.Second.ToString());

        }

    }

    #endregion

 

    class Program

    {

        static void Main(string[] args)

        {

            Clock theClock = new Clock();

            DisplayClock dc = new DisplayClock();

            dc.Subscribe(theClock);

            LogCurrentTime lct = new LogCurrentTime();

            lct.Subscribe(theClock);

            theClock.Run();

            Console.Read();

        }

    }

}

COMMENT USING