138

How can I make my own event in C#?

wonea
  • 4,783
  • 17
  • 86
  • 139
Gold
  • 60,526
  • 100
  • 215
  • 315

5 Answers5

240

Here's an example of creating and using an event with C#

using System;

namespace Event_Example
{
    //First we have to define a delegate that acts as a signature for the
    //function that is ultimately called when the event is triggered.
    //You will notice that the second parameter is of MyEventArgs type.
    //This object will contain information about the triggered event.
    public delegate void MyEventHandler(object source, MyEventArgs e);

    //This is a class which describes the event to the class that recieves it.
    //An EventArgs class must always derive from System.EventArgs.
    public class MyEventArgs : EventArgs
    {
        private string EventInfo;
        public MyEventArgs(string Text)
        {
            EventInfo = Text;
        }
        public string GetInfo()
        {
            return EventInfo;
        }
    }

    //This next class is the one which contains an event and triggers it
    //once an action is performed. For example, lets trigger this event
    //once a variable is incremented over a particular value. Notice the
    //event uses the MyEventHandler delegate to create a signature
    //for the called function.
    public class MyClass
    {
        public event MyEventHandler OnMaximum;
        private int i;
        private int Maximum = 10;
        public int MyValue
        {
            get
            {
                return i;
            }
            set
            {
                if(value <= Maximum)
                {
                    i = value;
                }
                else
                {
                    //To make sure we only trigger the event if a handler is present
                    //we check the event to make sure it's not null.
                    if(OnMaximum != null)
                    {
                        OnMaximum(this, new MyEventArgs("You've entered " +
                            value.ToString() +
                            ", but the maximum is " +
                            Maximum.ToString()));
                    }
                }
            }
        }
    }

    class Program
    {
        //This is the actual method that will be assigned to the event handler
        //within the above class. This is where we perform an action once the
        //event has been triggered.
        static void MaximumReached(object source, MyEventArgs e)
        {
            Console.WriteLine(e.GetInfo());
        }

        static void Main(string[] args)
        {
            //Now lets test the event contained in the above class.
            MyClass MyObject = new MyClass();
            MyObject.OnMaximum += new MyEventHandler(MaximumReached);

            for(int x = 0; x <= 15; x++)
            {
                MyObject.MyValue = x;
            }

            Console.ReadLine();
        }
    }
}
mattsson
  • 1,329
  • 1
  • 14
  • 30
Gary Willoughby
  • 50,926
  • 41
  • 133
  • 199
  • 6
    After visiting a hundred explanations, this finally helped me understand. SE was right, posts *are* still relevant after several years. –  Mar 27 '15 at 04:38
  • 1
    {Meh!} I always **forget** to write in the `event` portion for the class. –  Dec 23 '15 at 20:45
  • Who's still learning in 2022?? I know I am. Pretty cool you can create a custom event. – halshing Apr 18 '22 at 03:05
55

I have a full discussion of events and delegates in my events article. For the simplest kind of event, you can just declare a public event and the compiler will create both an event and a field to keep track of subscribers:

public event EventHandler Foo;

If you need more complicated subscription/unsubscription logic, you can do that explicitly:

public event EventHandler Foo
{
    add
    {
        // Subscription logic here
    }
    remove
    {
        // Unsubscription logic here
    }
}
Kevin Brown-Silva
  • 40,873
  • 40
  • 203
  • 237
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    I wasn't sure how to call the event from my code, but it turns out to be really obvious. You just call it like a method passing it a sender and EventArgs object. [ie. if (fooHappened) Foo(sender, eventArgs); ] – Richard Garside Sep 28 '12 at 11:27
  • 2
    @Richard: Not quite; you need to handle the case where there are no subscribers, so the delegate reference will be null. – Jon Skeet Sep 28 '12 at 11:48
  • Looking forward to the C# 4 update on thread safe events in the article you linked. Really great work, @JonSkeet! – kdbanman Aug 13 '15 at 22:28
24

You can declare an event with the following code:

public event EventHandler MyOwnEvent;

A custom delegate type instead of EventHandler can be used if needed.

You can find detailed information/tutorials on the use of events in .NET in the article Events Tutorial (MSDN).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Brann
  • 31,689
  • 32
  • 113
  • 162
6

to do it we have to know the three components

  1. the place responsible for firing the Event
  2. the place responsible for responding to the Event
  3. the Event itself

    a. Event

    b .EventArgs

    c. EventArgs enumeration

now lets create Event that fired when a function is called

but I my order of solving this problem like this: I'm using the class before I create it

  1. the place responsible for responding to the Event

    NetLog.OnMessageFired += delegate(object o, MessageEventArgs args) 
    {
            // when the Event Happened I want to Update the UI
            // this is WPF Window (WPF Project)  
            this.Dispatcher.Invoke(() =>
            {
                LabelFileName.Content = args.ItemUri;
                LabelOperation.Content = args.Operation;
                LabelStatus.Content = args.Status;
            });
    };
    

NetLog is a static class I will Explain it later

the next step is

  1. the place responsible for firing the Event

    //this is the sender object, MessageEventArgs Is a class I want to create it  and Operation and Status are Event enums
    NetLog.FireMessage(this, new MessageEventArgs("File1.txt", Operation.Download, Status.Started));
    downloadFile = service.DownloadFile(item.Uri);
    NetLog.FireMessage(this, new MessageEventArgs("File1.txt", Operation.Download, Status.Finished));
    

the third step

  1. the Event itself

I warped The Event within a class called NetLog

public sealed class NetLog
{
    public delegate void MessageEventHandler(object sender, MessageEventArgs args);

    public static event MessageEventHandler OnMessageFired;
    public static void FireMessage(Object obj,MessageEventArgs eventArgs)
    {
        if (OnMessageFired != null)
        {
            OnMessageFired(obj, eventArgs);
        }
    }
}

public class MessageEventArgs : EventArgs
{
    public string ItemUri { get; private set; }
    public Operation Operation { get; private set; }
    public Status Status { get; private set; }

    public MessageEventArgs(string itemUri, Operation operation, Status status)
    {
        ItemUri = itemUri;
        Operation = operation;
        Status = status;
    }
}

public enum Operation
{
    Upload,Download
}

public enum Status
{
    Started,Finished
}

this class now contain the Event, EventArgs and EventArgs Enums and the function responsible for firing the event

sorry for this long answer

Basheer AL-MOMANI
  • 14,473
  • 9
  • 96
  • 92
  • They key difference in this answer is making the event static, which allows events to be received without requiring a reference to the object which fired the event. Great for subscribing to events from multiple independent controls. – Radderz Oct 24 '18 at 10:19
1

In order to achieve this you need to create an event, its handler and a delegate. Also you need to subscribe to the event and fire it.

A delegate defines the signature of the event handler method that will handle the event. That would be your code. For example:

public static void MyEventHandlerMethod(object sender, EventArgs e)
{
    Console.WriteLine("Event handled");
}

You can use the following line to declare the event:

public event MyEventHandler MyEvent;

In order to activate the handler it is necessary to subscribe to the event:

MyEvent += MyEventHandlerMethod;

Now you just need to fire your event. You probably want to create another method for this:

public void FireMyEvent()
{
  if (MyEvent != null) // check if the event is not null (for ex. if the eventhandler was not subscribed)
  {
     MyEvent(this, EventArgs.Empty);
  }

}
timkicker
  • 13
  • 4