Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / C#

Learning C# (Day 9): Understanding Events in C# (An Insight)

,
Rate me:
Please Sign up or sign in to vote.
4.31/5 (68 votes)
21 Jul 2015CPOL10 min read 115.4K   4.6K   83   45
Understanding Events in C# (An Insight)

Table of Contents

Introduction

Events are one of the core and important concepts of C# Programming environment and frankly speaking sometimes it’s hard to understand them without proper explanation and example.

So I thought of writing this article to make things easier for learners and beginners.

Image 1

Image credit: http://d.wildapricot.net/images/newsblog/bigstock-events-19983578.jpg?sfvrsn=0

Roadmap

Let’s revise our road map once again,

  1. Diving in OOP (Day 1): Polymorphism and Inheritance(Early Binding/Compile Time Polymorphism)
  2. Diving in OOP (Day 2): Polymorphism and Inheritance (Inheritance)
  3. Diving in OOP (Day 3): Polymorphism and Inheritance (Dynamic Binding/Run Time Polymorphism)
  4. Diving in OOP (Day 4): Polymorphism and Inheritance (All about Abstarct classes in C#)
  5. Diving in OOP (Day 5): All about access modifiers in C# (Public/Private/Protected/Internal/Sealed/Constants/Readonly Fields)
  6. Learning C# (Day 6): Understanding Enums in C# (A Practical Approach)
  7. Learning C# (Day 7): Properties in C# (A Practical Approach)
  8. Learning C# (Day 8): Indexers in C# (A Practical Approach)
  9. Learning C# (Day 9): Understanding Events in C# (An Insight)
  10. Learning C# (Day 10): Delegates in C# (A Practical Approach)
  11. Learning C# (Day 11): Events in C# (A Practical Approach)

Our Topic

An event in a very simple language is an action or occurrence, such as clicks, key press, mouse movements, or system generated notifications. Application can respond to events when they occur. Events are messages sent by the object to indicate the occurrence of the event. Events are an effective mean of inter-process communication. They are useful for an object because they provide signal state changes, which may be valuable to a client of the object.

If above sentences were tough to understand let’s put this simple if a button on a form gets clicked by a user an event gets fired, if a user type something on a textbox keys gets pressed and hence an event gets fired an so on.

Explanation from MSDN,

"An event in C# is a way for a class to provide notifications to clients of that class when some interesting thing happens to an object. The most familiar use for events is in graphical user interfaces; typically, the classes that represent controls in the interface have events that are notified when the user does something to the control (for example, click a button).

Events, however, need not be used only for graphical interfaces. Events provide a generally useful way for objects to signal state changes that may be useful to clients of that object. Events are an important building block for creating classes that can be reused in a large number of different programs.

Events are declared using delegates. If you have not yet studied the Delegates Tutorial, you should do so before continuing. Recall that a delegate object encapsulates a method so that it can be called anonymously. An event is a way for a class to allow clients to give it delegates to methods that should be called when the event occurs. When the event occurs, the delegate(s) given to it by its clients are invoked."

The following figure is the generalized representation that explains events and event handling.

Image 2

In C#, delegates are used with events to implement event handling. The .NET Framework event model uses delegates to bind notifications with methods known as event handlers. When an event is generated, the delegate calls the associated event handler.

Investigating .NET Windows Application Button Click Event (A case study)

Just open your visual studio and create one windows application. You’ll get a form in your windows application project named Form1.cs. Add a simple button to that form, just drag and drop. In properties panel of that button, bind the on click event of that button with an event at code behind and show some text on its click. You can browse the attached source code for understanding.

Now when you run the application, your form will be shown with just one button, click that button and see what happens,

Image 3

As we can see button on the form was clicked by the user and hence button click event was fired which was handled by Delegate which in turn called button_click method (Event handler method) which showed our Message Box.

In above example Event declaration, Delegate declaration, Event handler declaration all done by .NET we just have to write code handle to our event in this case code to display message box.

Behind the curtain

If we investigate Form1.Designer.cs and follow the step shown in figure below we can easily find out the event keyword and delegate keyword and hence find out their definition.

Since we haven’t seen the definition syntax it might looks alien to you but we will get to it soon but for now just follow the steps in figure.

Step 1: Open Form1.Designer.Cs from solution explorer

Image 4

Step 2: In Form1.Designer.Cs Click event and EventHandler delegate.

Image 5

Step 3: Double click this.button1.Click and Press F12 to see Click Event definition, similarly double click System.EventHandler and Press F12 to see EventHandler Delegate definition.

Event’s definition,

Image 6

Delegate’s definition,

Image 7

Publisher-Subscriber model

The events are declared and raised in a class and associated with the event handlers using delegates within the same class or other classes. Events are part of a class and the same class is used to publish its events. The other classes can, however, accept these events or in other words can subscribe to these events. Events use the publisher and subscriber model.

 

Image 8

A publisher is an object that contains the definition of the event and the delegate. The association of the event with the delegate is also specified in the publisher class. The object of the publisher class invokes the event, which is notified to the other objects.

A subscriber is an object that wants to accept the event and provide a handler to the event. The delegate of the publisher class invokes the method of the subscriber class. This method in the subscriber class is the event handler. The publisher and subscriber model implementation can be defined by the same class.

Delegates play a very important role in C#, it is one of the entities that can be directly put into a namespace of a class. This quality of delegate makes it accessible to all other classes as well. Delegates work on Object oriented pattern and try to follow encapsulation by enclosing method and object together. Delegate in C# define a class and uses namespace System.Delegate. Delegates are ideal for anonymous method invocation. I’ll discuss events and delegates in more detail in my upcoming articles.

The following figure shows the mechanism used by the publisher and subscriber objects.

Image 9

Getting your hands dirty: Creating custom event

Let’s get our hand dirty by building our own event handling example. In the example below we will see how to define our customized event and how to raise it and how to handle it by our own customized event handler.

In our simple example we’ll build a console application for Bank, in which an event TransactionMade is raised whenever the Customer makes a transaction and in response a notification is send to him.

Let’s do some serious coding now.

First we define our class Account.

We can add a constructor to initialize our variable int BalanceAmount which will hold the account balance in our class.

C#
public int BalanceAmount;
 public Account(int amount)
 {
     BalanceAmount = amount;
 }

Then we define our event and our delegate.

The definition of the event in a publisher class (Account class ) includes the declaration of the delegate as well as the declaration of the event based on the delegate. The following code defines a delegate named TransactionHandler and an event TransactionMade, which invokes the TransactionHandler delegate when it is raised:

C#
 public delegate void TransactionHandler(object sender,TransactionEventArgs e);
public event TransactionHandler TransactionMade;

As you see, our delegate's name is TransactionHandler, and its signature contains a void return value and two parameters of type object and TransactionEventArgs. If you somewhere want to instantiate this delegate, the function passed in as constructor parameter should have the same signature as this delegate.

When an event is raised we pass some data to subscriber in a class which is derived from. For example, in our example we want to provide the Transaction Amount and the Type of Transaction made. So we define a class TransactionEventArgs which will inherit EventArgs to pass data to subscriber class. We have declared two private variables one int _transactionAmount to pass transaction amount information and other is string _transactionType to pass transaction type (Credit/Debit) information to subscriber class.

And here is the class definition:

C#
public class TransactionEventArgs : EventArgs
  {
      public int TranactionAmount { get; set; }
      public string TranactionType { get; set; }

      public TransactionEventArgs(int amt, string type)
      {
          TranactionAmount = amt;
          TranactionType = type;
      }
  }

Now, everything is in our Account class. Now we will define our notifier methods which will be invoke on credit or debit transaction and raise our event.

In Debit Method balance amount will be deducted and event will be raised to notify subscriber that the balance amount has been changed, similarly in case of Credit method balance amount will be credited and notification will be sent to subscriber class.

Debit Method

C#
public void Debit(int debitAmount)
       {
           if (debitAmount < BalanceAmount)
           {
               BalanceAmount = BalanceAmount - debitAmount;
               TransactionEventArgs e = new TransactionEventArgs(debitAmount,"Debited");
               OnTransactionMade(e); // Debit transaction made
           }
       }

Credit Method

C#
public void Credit(int creditAmount)
   {

       BalanceAmount = BalanceAmount + creditAmount;
       TransactionEventArgs e = new TransactionEventArgs(creditAmount,"Credited");
        OnTransactionMade(e); // Credit transaction made

   }

As you can see in above methods we have created instance of TransactionEventArgs and we passed that instance in OnTransactionMade() method, and called it. You must be thinking what OnTransactionMade() is doing here well this is our method which is raising our event. So here is its definition:

C#
protected virtual void OnTransactionMade(TransactionEventArgs e)
   {
       if (TransactionMade != null)
       {
           TransactionMade(this, e); // Raise the event
       }
   }

Below is the complete code for our Account Class:

C#
namespace EventExample
{
 public delegate void TransactionHandler(object sender,TransactionEventArgs e); // Delegate Definition
    class Account
    {
        public event TransactionHandler TransactionMade; // Event Definition

        public int BalanceAmount;

       public Account(int amount)
        {
            this.BalanceAmount = amount;
 
        }

        public void Debit(int debitAmount)
        {
            if (debitAmount < BalanceAmount)
            {
                BalanceAmount = BalanceAmount - debitAmount;
                TransactionEventArgs e = new TransactionEventArgs(debitAmount,"Debited");
                OnTransactionMade(e); // Debit transaction made
            }
        }

        public void Credit(int creditAmount)
        {

            BalanceAmount = BalanceAmount + creditAmount;
            TransactionEventArgs e = new TransactionEventArgs(creditAmount,"Credited");
             OnTransactionMade(e); // Credit transaction made
            
        }

        protected virtual void OnTransactionMade(TransactionEventArgs e)
        {
            if (TransactionMade != null)
            {
                TransactionMade(this, e); // Raise the event 
            }
        }
    }

Raising an event is accomplished through calling our event TransactionMade(this, e);

And this event will be handled by our event handler.

Now let’s define our Subscriber class which will react on event and process it accordingly through its own methods.

First create a class named TestMyEvent and define a method SendNotification, its return type and parameter should match our Delegate declared earlier in publisher class. Basically this method will react on event which is change in our balance amount and inform user user (by writing this on console).

Below is definition:

C#
private static void SendNotification(object sender, TransactionEventArgs e)
    {
        Console.WriteLine("Your Account is {0} for Rs.{1} ", e.TranactionType, e.TranactionAmount);
     }

Now in Main() method of subscriber class create instance of and pass some initial balance amount. Then reference of event handler is passed to the event and method to be called on that event response is passed to the event handler.

C#
private static void Main()
       {
           Account MyAccount = new Account(10000);
           MyAccount.TransactionMade += new TransactionHandler(SendNotification);
           MyAccount.Credit(500);
           Console.WriteLine("Your Current Balance is : " + MyAccount.BalanceAmount);
           Console.ReadLine();


       }

So, below is the complete definition of our subscriber class (TestMyEvent):

C#
class TestMyEvent
    {
        
        private static void SendNotification(object sender, TransactionEventArgs e)
        {
      Console.WriteLine("Your Account is {0} for Rs.{1} ", e.TranactionType, e.TranactionAmount);
 
        }

        private static void Main()
        {
            Account MyAccount = new Account(10000);
            MyAccount.TransactionMade += new TransactionHandler(SendNotification);
            MyAccount.Credit(500);
            Console.WriteLine("Your Current Balance is : " + MyAccount.BalanceAmount);
            Console.ReadLine();

        }
    }

Our output will be:

Image 10

Code explanation

Image 11

In our example our Account Class is the publisher which notifies the change in account balance if debit or credit is made as you can see from code we have raised our event in Debit/Credit method and if event is raised then somebody has to act upon it so TestMyEvent Class is the subscriber class in which Debit/Credit transaction is made hence change in Account Balance so it gets notification from the Publisher Class and it acts upon it and handles the event by calling its event handler method SendNotification. So it’s pretty much clear here that events can be defined in one class(Publisher) and several subscriber class can acts upon it depending on their own need.

Conclusion

We investigated .NET events and build our own custom event and saw how events are raised and handled. So I wouldn’t be wrong to say that events encapsulate delegates and delegates encapsulate methods. So the subscriber class doesn’t need to know what’s happening behind the curtain it just requires notification from the publisher class that an event has been raised and have to respond accordingly.

Image 12

I hope you are satisfied after reading the article and most of all you enjoyed while reading and coding.

Image 13

My other series of articles:

MVChttp://www.codeproject.com/Articles/620195/Learning-MVC-Part-Introduction-to-MVC-Architectu

RESTful WebAPIshttp://www.codeproject.com/Articles/990492/RESTful-Day-sharp-Enterprise-Level-Application

Happy coding !

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect https://codeteddy.com/
India India
Akhil Mittal is two times Microsoft MVP (Most Valuable Professional) firstly awarded in 2016 and continued in 2017 in Visual Studio and Technologies category, C# Corner MVP since 2013, Code Project MVP since 2014, a blogger, author and likes to write/read technical articles, blogs, and books. Akhil is a technical architect and loves to work on complex business problems and cutting-edge technologies. He has an experience of around 15 years in developing, designing, and architecting enterprises level applications primarily in Microsoft Technologies. He has diverse experience in working on cutting-edge technologies that include Microsoft Stack, AI, Machine Learning, and Cloud computing. Akhil is an MCP (Microsoft Certified Professional) in Web Applications and Dot Net Framework.
Visit Akhil Mittal’s personal blog CodeTeddy (CodeTeddy ) for some good and informative articles. Following are some tech certifications that Akhil cleared,
• AZ-304: Microsoft Azure Architect Design.
• AZ-303: Microsoft Azure Architect Technologies.
• AZ-900: Microsoft Azure Fundamentals.
• Microsoft MCTS (70-528) Certified Programmer.
• Microsoft MCTS (70-536) Certified Programmer.
• Microsoft MCTS (70-515) Certified Programmer.

LinkedIn: https://www.linkedin.com/in/akhilmittal/
This is a Collaborative Group

779 members

Written By
Software Developer (Senior)
India India
I am currently working as a Senior Software Engineer in Quovantis Technologies and have an experience of more than 4 years in C#.Net. I have my graduation in Bachelor of Computer Applications and hold a diploma in Software Engineering GNIIT from NIIT.
I am very passionate about programming, love to learn new technology and believe in sharing knowledge.
My work experience includes Development of Enterprise Applications using C#,.Net,Sql Server,AngularJS and Javascript.

Comments and Discussions

 
SuggestionEvent Broker Pin
godlotom12-Feb-17 12:27
godlotom12-Feb-17 12:27 
QuestionWhy not Interface Pin
ravi_24prakash6-May-16 1:40
ravi_24prakash6-May-16 1:40 
QuestionA good practical example, suggestion for continuation of the series - "Most common Design Patterns" Pin
diman8215-Feb-16 4:54
diman8215-Feb-16 4:54 
GeneralMy vote of 5 Pin
Akhilesh K13-Dec-15 20:15
Akhilesh K13-Dec-15 20:15 
GeneralRe: My vote of 5 Pin
Akhil Mittal17-Dec-15 19:03
professionalAkhil Mittal17-Dec-15 19:03 
GeneralGeneral Notes Pin
Pawan.riseup10-Dec-15 19:42
Pawan.riseup10-Dec-15 19:42 
GeneralRe: General Notes Pin
Akhil Mittal17-Dec-15 19:04
professionalAkhil Mittal17-Dec-15 19:04 
GeneralMy vote of 5 Pin
D V L13-Sep-15 19:33
professionalD V L13-Sep-15 19:33 
GeneralRe: My vote of 5 Pin
Akhil Mittal13-Sep-15 19:52
professionalAkhil Mittal13-Sep-15 19:52 
GeneralMy vote of 5 Pin
Oshtri Deka13-Aug-15 11:48
professionalOshtri Deka13-Aug-15 11:48 
GeneralRe: My vote of 5 Pin
Akhil Mittal13-Aug-15 17:33
professionalAkhil Mittal13-Aug-15 17:33 
Questiongood Pin
sachin verma7-Aug-15 2:37
professionalsachin verma7-Aug-15 2:37 
AnswerRe: good Pin
Akhil Mittal7-Aug-15 3:00
professionalAkhil Mittal7-Aug-15 3:00 
GeneralMy vote of 5 Pin
DrABELL7-Aug-15 1:43
DrABELL7-Aug-15 1:43 
GeneralRe: My vote of 5 Pin
Akhil Mittal7-Aug-15 2:31
professionalAkhil Mittal7-Aug-15 2:31 
GeneralRe: My vote of 5 Pin
DrABELL7-Aug-15 8:45
DrABELL7-Aug-15 8:45 
GeneralMy vote of 5 Pin
Suvendu Shekhar Giri6-Aug-15 0:12
professionalSuvendu Shekhar Giri6-Aug-15 0:12 
Nice article.
GeneralRe: My vote of 5 Pin
Akhil Mittal6-Aug-15 17:07
professionalAkhil Mittal6-Aug-15 17:07 
GeneralGood Job Bro.... Pin
Member 1134613928-Jul-15 1:33
Member 1134613928-Jul-15 1:33 
GeneralRe: Good Job Bro.... Pin
Akhil Mittal29-Jul-15 3:36
professionalAkhil Mittal29-Jul-15 3:36 
GeneralGood post Pin
SergheiT23-Jul-15 6:12
professionalSergheiT23-Jul-15 6:12 
GeneralRe: Good post Pin
Akhil Mittal26-Jul-15 5:43
professionalAkhil Mittal26-Jul-15 5:43 
GeneralMy vote of 5 Pin
prashita gupta21-Jul-15 3:02
prashita gupta21-Jul-15 3:02 
GeneralRe: My vote of 5 Pin
Akhil Mittal21-Jul-15 3:12
professionalAkhil Mittal21-Jul-15 3:12 
QuestionNice Pin
udeep kansal21-Jul-15 1:45
professionaludeep kansal21-Jul-15 1:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.