---
title: "Manage many events easily with EventHandlerList"
url: "https://osherove.com/blog/2004/12/31/manage-many-events-easily-with-eventhandlerlist.md"
canonical: "https://osherove.com/blog/2004/12/31/manage-many-events-easily-with-eventhandlerlist.html"
published: "2004-12-31T11:56:00"
updated: "2004-12-31T11:56:00"
tags: [".Net Original", "Tips & Tricks"]
author: "Roy Osherove"
description: "There were many little snippets and corners during Juval's class that simply made my day every time. This is one of those. What happens when you have a class that exposes many events (such as the \"Button\" or \"Control\"…"
usage: "Licensed under CC BY 4.0 — reuse, quote and adapt with attribution (Roy Osherove, link to the original page)."
license: "https://creativecommons.org/licenses/by/4.0/"
---

# Manage many events easily with EventHandlerList

By Roy Osherove December 31, 2004 In [.Net Original](https://osherove.com/blog/category/net-original), [Tips & Tricks](https://osherove.com/blog/category/tips-tricks)

**Historical article** · Originally published December 31, 2004; technical details may be outdated.

There were many little snippets and corners during [Juval's class](http://www.idesign.net/) that simply made my day every time. This is one of those.

What happens when you have a class that exposes many events (such as the "Button" or "Control" class that exposes "Click","Focus" etc..)? In the standard case you would have to have many delegates as members inside it and that would make your code look very messy. The _Simpler_ soution however would be to use the **_EventHandlerList_** class that is found in the **_System.ComponentModel_** namespace. It's basically a hashtable of all the event handlers you want to keep (the delegates, actually) and allows you to use it for general event storing purposes. In fact, the **Control** class in the .Net framework use this internally to store its own events.

How do you use it? You implement the specific "add" and "remove" accessors for your events, and inside them, you redirect the added or removed delegate value into the _EventHandlerList_ object. Like so:

private EventHandlerList m\_handlers = new EventHandlerList();

public event EventHandler Saved

 {

   add

   {

    m\_handlers.AddHandler("Saved",value);

   }

   remove

   {

    m\_handlers.RemoveHandler("Saved",value);

   }

 }

Unfortunately, this cannot be done in VB.Net (you can't override event accessors in VB.Net!?).

Here's an implementation of a class that exposes 3 events, one of them is not a simple event handler type. You'll see that it's just as simple to exposes them, but only one member holds all the events.

      public class MyComplicatedClass

      {

            public delegate void SpecialEventDelegate(string someText,int someNumber);

            private EventHandlerList m\_handlers = new EventHandlerList();

            public event EventHandler Saved

            {

                  add

                  {

                        m\_handlers.AddHandler("Saved",value);

                  }

                  remove

                  {

                        m\_handlers.RemoveHandler("Saved",value);

                  }

            }

            public event EventHandler Deleted

            {

                  add

                  {

                        m\_handlers.AddHandler("Deleted",value);

                  }

                  remove

                  {

                        m\_handlers.RemoveHandler("Deleted",value);

                  }

            }

            public event SpecialEventDelegate SpecialEvent

            {

                  add

                  {

                        m\_handlers.AddHandler("SpecialEvent",value);

                  }

                  remove

                  {

                        m\_handlers.RemoveHandler("SpecialEvent",value);

                  }

            }

            private void FireSavedEvent()

            {

                  EventHandler handler = (EventHandler)m\_handlers\["Saved"\];

                  if(handler!=null)

                  {

                        handler(this,new EventArgs());

                  }

            }

            private void FireDeletedEvent()

            {

                  EventHandler handler = (EventHandler)m\_handlers\["Deleted"\];

                  if(handler!=null)

                  {

                        handler(this,new EventArgs());

                  }

            }

            private void FireSpecialEvent()

            {

                  SpecialEventDelegate handler = (SpecialEventDelegate) m\_handlers\["SpecialEvent"\];

                  int someNumber\=3;

                  if(handler!=null)

                  {

                        handler("some text",someNumber);

                  }

            }

      }

## More in .Net Original

[All posts in .Net Original](https://osherove.com/blog/category/net-original)

- Jan 6, 2005

    ### [Return of the Extensibility Application Block](https://osherove.com/blog/2005/1/6/return-of-the-extensibility-application-block.html)

- Jan 5, 2005

    ### [A simple question about overloading](https://osherove.com/blog/2005/1/5/a-simple-question-about-overloading.html)

- Dec 30, 2004

    ### [Next generation iteration: Array.ForEach and Delegate inference](https://osherove.com/blog/2004/12/30/next-generation-iteration-arrayforeach-and-delegate-inferenc.html)

- Dec 29, 2004

    ### [Do not serialize delegates and events blindly](https://osherove.com/blog/2004/12/29/do-not-serialize-delegates-and-events-blindly.html)


---

## About the author

**Roy Osherove**: Senior Solutions Architect at AWS working on AI for production and AI-driven development; author of The Art of Unit Testing and Elastic Leadership, with about 20 years of consulting and training on unit testing, TDD, team leadership and continuous delivery.

### Sites

- [RobotPaper](https://robotpaper.ai/): This blog: AI patterns and anti-patterns, AI and coding agents, and engineering leadership.
- [osherove.com](https://osherove.com): Roy's personal site. Author of The Art of Unit Testing and Elastic Leadership; consulting and training on unit testing, TDD, team leadership and continuous delivery, plus about 20 years of blog posts.
- [The Art of Unit Testing](https://www.artofunittesting.com): The Art of Unit Testing, 3rd Edition (Manning): readable, maintainable, trustworthy unit tests, plus TDD workshops in C#, JavaScript, Java and Kotlin.
- [5whys.com](https://www.5whys.com): Roy's writing on software team leadership: self-organizing teams, surviving chaos, learning mode and the Elastic Leadership model.
- [Pipeline Driven](https://pipelinedriven.org): Continuous delivery and DevOps practices: build patterns, pipeline-friendly testing, DevOps metrics and enterprise DevOps.
- [Elastic Leadership](https://www.elasticleadership.com): Elastic Leadership, Roy's framework for software team leaders (survival, learning and self-organizing modes).

### Social

- X: https://x.com/royosherove
- LinkedIn: https://www.linkedin.com/in/osherove/

### Contact

- Contact form: https://forms.gle/jQSx5KoXvrVA1JCK7

### License

Licensed under CC BY 4.0 — reuse, quote and adapt with attribution (Roy Osherove, link to the original page). License: https://creativecommons.org/licenses/by/4.0/
