How to: Create Events that Conform to .NET Framework Guidelines (C# Programming Guide) 

The C# language allows an event to use any delegate type, but the .NET Framework has stricter guidelines for delegates and events. If you intend for your component to be used with the .NET Framework, you probably will want to follow these guidelines.

The .NET Framework guidelines indicate that the delegate type used for an event should take two parameters: an object source parameter indicating the source of the event, and an event-specific parameter that encapsulates any additional information about the event. The event-specific parameter should derive from the EventArgs class. For events that do not use any additional information, the .NET Framework provides the EventHandler class.

The following example is like the code in How to: Create a Control that Responds to Events (C# Programming Guide), except that this version follows the .NET Framework guidelines.

Example

namespace TestCollections
{
    // A class that works just like ArrayList, but sends event
    // notifications whenever the list changes:
    public class ListWithChangedEvent : System.Collections.ArrayList
    {
        // An event that clients can use to be notified whenever the
        // elements of the list change:
        public event System.EventHandler Changed;

        // Invoke the Changed event; called whenever list changes:
        protected virtual void OnChanged(System.EventArgs e)
        {
            if (Changed != null)
            {
                Changed(this, e);
            }
        }

        // Override some of the methods that can change the list;
        // invoke event after each:
        public override int Add(object value)
        {
            int i = base.Add(value);
            OnChanged(System.EventArgs.Empty);
            return i;
        }

        public override void Clear()
        {
            base.Clear();
            OnChanged(System.EventArgs.Empty);
        }

        public override object this[int index]
        {
            set
            {
                base[index] = value;
                OnChanged(System.EventArgs.Empty);
            }
        }
    }
}

namespace TestEvents
{
    using TestCollections;

    class EventListener
    {
        private ListWithChangedEvent m_list;

        public EventListener(ListWithChangedEvent list)
        {
            m_list = list;

            // Add "ListChanged" to the Changed event on m_list:
            m_list.Changed += new System.EventHandler(ListChanged);
        }

        // This will be called whenever the list changes:
        private void ListChanged(object sender, System.EventArgs e)
        {
            System.Console.WriteLine("This is called when the event fires.");
        }

        public void Detach()
        {
            // Detach the event and delete the list:
            m_list.Changed -= new System.EventHandler(ListChanged);
            m_list = null;
        }
    }

    class Test
    {
        // Test the ListWithChangedEvent class:
        static void Main()
        {
            // Create a new list:
            ListWithChangedEvent list = new ListWithChangedEvent();

            // Create a class that listens to the list's change event:
            EventListener listener = new EventListener(list);

            // Add and remove items from the list:
            list.Add("item 1");
            list.Clear();
            listener.Detach();
        }
    }
}

Output

This is called when the event fires.
This is called when the event fires.

See Also

Reference

Delegate

Concepts

C# Programming Guide
Events (C# Programming Guide)
Delegates (C# Programming Guide)