Skip to content

Commit 84681d1

Browse files
adegeoBillWagner
andauthored
Clean up events docs (#52607)
* Update snippets * Fix ASP.NET references * Misc * Convert all snippets of article * move snippets * rewrite and adjust snippet refs * Move to sensor example * Rewrite multiple events article * Remove redundant keywords * Rewrite intro. Much better * Clean up code a little * Fix inline code * Change titles from handle to declare * minor edits * Rename 'handle multiple' to 'declare multiple' * Revert redirect * fix redirects * Fix title in toc * Apply suggestion from @BillWagner Co-authored-by: Bill Wagner <wiwagn@microsoft.com> * Spacing in code --------- Co-authored-by: Bill Wagner <wiwagn@microsoft.com>
1 parent 28339db commit 84681d1

30 files changed

Lines changed: 1050 additions & 226 deletions

.openpublishing.redirection.standard.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,10 @@
403403
"source_path_from_root": "/docs/standard/events/how-to-consume-events-in-a-web-forms-application.md",
404404
"redirect_url": "/aspnet/web-forms/overview/how-to-consume-events"
405405
},
406+
{
407+
"source_path_from_root": "/docs/standard/events/how-to-handle-multiple-events-using-event-properties.md",
408+
"redirect_url": "/dotnet/standard/events/how-to-declare-multiple-events-using-event-properties"
409+
},
406410
{
407411
"source_path_from_root": "/docs/standard/exceptions.md",
408412
"redirect_url": "/dotnet/standard/exceptions/",

docs/fundamentals/toc.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,8 @@ items:
341341
displayName: events
342342
- name: Raise and consume events
343343
href: ../standard/events/how-to-raise-and-consume-events.md
344-
- name: Handle multiple events using event properties
345-
href: ../standard/events/how-to-handle-multiple-events-using-event-properties.md
344+
- name: Declare multiple events using event properties
345+
href: ../standard/events/how-to-declare-multiple-events-using-event-properties.md
346346
- name: Observer design pattern
347347
items:
348348
- name: Overview
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
title: "Declare multiple events using event properties"
3+
description: Learn how to declare many events by using event properties. Define delegate collections, event keys, and event properties. Implement add and remove accessor methods.
4+
ms.date: 03/25/2026
5+
ms.topic: how-to
6+
dev_langs:
7+
- "csharp"
8+
- "vb"
9+
helpviewer_keywords:
10+
- "event properties [.NET]"
11+
- "multiple events [.NET]"
12+
- "event handling [.NET], with multiple events"
13+
- "events [.NET], multiple"
14+
ai-usage: ai-assisted
15+
---
16+
17+
# Declare multiple events using event properties
18+
19+
When a class defines many events using field-like event declarations, the compiler generates a backing field for each one. Every instance of that class allocates memory for all of those fields—even for events that are never subscribed. With many events, this per-instance overhead wastes memory.
20+
21+
To avoid this memory overhead, use event properties backed by a delegate collection. The collection must provide methods that set, access, and retrieve delegates by event key. <xref:System.ComponentModel.EventHandlerList> is designed for this purpose, but you can also use a <xref:System.Collections.Hashtable> or a class derived from <xref:System.Collections.DictionaryBase>. Keep the collection's implementation details private.
22+
23+
Each event property defines an add accessor and a remove accessor. The add accessor adds the input delegate to the delegate collection, and the remove accessor removes it. Both accessors use a predefined key to add and remove instances from the collection.
24+
25+
## Prerequisites
26+
27+
Familiarize yourself with the concepts in the [Events](index.md) article.
28+
29+
## Define multiple events using event properties
30+
31+
These steps create a `Sensor` class that exposes 10 event properties, all backed by a single `EventHandlerList`.
32+
33+
1. Define an event data class that inherits from <xref:System.EventArgs>.
34+
35+
Add properties for each piece of data you want to pass to the handler:
36+
37+
:::code language="csharp" source="./snippets/how-to-handle-multiple-events-using-event-properties/csharp/Sensor.cs" id="SensorEventArgs":::
38+
:::code language="vb" source="./snippets/how-to-handle-multiple-events-using-event-properties/vb/Sensor.vb" id="SensorEventArgs":::
39+
40+
1. Declare an <xref:System.ComponentModel.EventHandlerList> field to store the delegates:
41+
42+
:::code language="csharp" source="./snippets/how-to-handle-multiple-events-using-event-properties/csharp/Sensor.cs" id="EventHandlerListField":::
43+
:::code language="vb" source="./snippets/how-to-handle-multiple-events-using-event-properties/vb/Sensor.vb" id="EventHandlerListField":::
44+
45+
1. Declare a unique key for each event.
46+
47+
`EventHandlerList` stores delegates by key. Use a `static readonly` object (`Shared ReadOnly` in Visual Basic) for each key—object identity ensures each key is truly unique:
48+
49+
:::code language="csharp" source="./snippets/how-to-handle-multiple-events-using-event-properties/csharp/Sensor.cs" id="EventKeys":::
50+
:::code language="vb" source="./snippets/how-to-handle-multiple-events-using-event-properties/vb/Sensor.vb" id="EventKeys":::
51+
52+
1. Define each event as an event property with custom add and remove accessors.
53+
54+
Each accessor calls `AddHandler` or `RemoveHandler` on the list using that event's key. In C#, also add a `protected virtual` raise method that retrieves the delegate from the list by key and invokes it. In Visual Basic, the `Custom Event` declaration already includes a `RaiseEvent` block that does this:
55+
56+
:::code language="csharp" source="./snippets/how-to-handle-multiple-events-using-event-properties/csharp/Sensor.cs" id="SingleEventProperty":::
57+
:::code language="vb" source="./snippets/how-to-handle-multiple-events-using-event-properties/vb/Sensor.vb" id="SingleEventProperty":::
58+
59+
Repeat this pattern for each event, using its corresponding key.
60+
61+
1. Subscribe to the event using the `+=` operator (in Visual Basic, `AddHandler`):
62+
63+
:::code language="csharp" source="./snippets/how-to-handle-multiple-events-using-event-properties/csharp/Program.cs" id="SubscribeEvent":::
64+
:::code language="vb" source="./snippets/how-to-handle-multiple-events-using-event-properties/vb/Program.vb" id="SubscribeEvent":::
65+
66+
1. Define the event handler.
67+
68+
The signature must match the <xref:System.EventHandler`1> delegate—an `object` sender and your event data class as the second parameter:
69+
70+
:::code language="csharp" source="./snippets/how-to-handle-multiple-events-using-event-properties/csharp/Program.cs" id="HandleEvent":::
71+
:::code language="vb" source="./snippets/how-to-handle-multiple-events-using-event-properties/vb/Program.vb" id="HandleEvent":::
72+
73+
The following example shows the complete `Sensor` class implementation:
74+
75+
:::code language="csharp" source="./snippets/how-to-handle-multiple-events-using-event-properties/csharp/Sensor.cs" id="EventProperties":::
76+
:::code language="vb" source="./snippets/how-to-handle-multiple-events-using-event-properties/vb/Sensor.vb" id="EventProperties":::
77+
78+
## Related content
79+
80+
- <xref:System.ComponentModel.EventHandlerList?displayProperty=nameWithType>
81+
- [Events](index.md)

docs/standard/events/how-to-handle-multiple-events-using-event-properties.md

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)