Skip to content

Commit b186a51

Browse files
authored
Merge pull request #50095 from wwlpublish/6b0119dd0b18544fde9c5831565e81479ab389e6da431ddd3fe90be436591c3a-live
Modules/M02-create-manage-events
2 parents 015a8b4 + cc7cae7 commit b186a51

19 files changed

+754
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.create-manage-events.introduction
3+
title: Introduction
4+
metadata:
5+
title: Introduction
6+
description: "Introduction to the module."
7+
ms.date: 04/24/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 2
12+
content: |
13+
[!include[](includes/1-introduction.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.create-manage-events.examine-events-csharp
3+
title: Examine events in C#
4+
metadata:
5+
title: Examine events in C#
6+
description: "Learn how events in C# enable communication between objects and streamline user interactions."
7+
ms.date: 04/24/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 6
12+
content: |
13+
[!include[](includes/2-examine-events-csharp.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.create-manage-events.declare-events-csharp
3+
title: Declare events in C#
4+
metadata:
5+
title: Declare events in C#
6+
description: "Learn how to declare events in C# and use delegates to enable communication between components."
7+
ms.date: 04/24/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 6
12+
content: |
13+
[!include[](includes/3-declare-events-csharp.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.create-manage-events.subscribe-unsubscribe-events-csharp
3+
title: Subscribe and unsubscribe from events in C#
4+
metadata:
5+
title: Subscribe and unsubscribe from events in C#
6+
description: "Learn how to manage event subscriptions and unsubscriptions to ensure efficient resource usage."
7+
ms.date: 04/24/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 8
12+
content: |
13+
[!include[](includes/4-subscribe-unsubscribe-events-csharp.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.create-manage-events.explore-delegates-events-relationship-csharp
3+
title: Explore delegates and events relationship in C#
4+
metadata:
5+
title: Explore delegates and events relationship in C#
6+
description: "Understand advanced concepts of delegates and events in C#, including custom event data, multicast delegates, and best practices."
7+
ms.date: 04/24/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 8
12+
content: |
13+
[!include[](includes/5-explore-delegates-events-relationship-csharp.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.create-manage-events.exercise-implement-events-csharp
3+
title: 'Exercise: Implement events in C#'
4+
metadata:
5+
title: 'Exercise: Implement events in C#'
6+
description: "Practice creating, subscribing to, and raising events in C# using delegates and custom event data classes."
7+
ms.date: 04/24/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 25
12+
content: |
13+
[!include[](includes/6-exercise-implement-events-csharp.md)]
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.create-manage-events.knowledge-check
3+
title: Module assessment
4+
metadata:
5+
title: Module assessment
6+
description: "Check what you've learned in this module."
7+
ms.date: 04/24/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 3
12+
content: |
13+
[!include[](includes/7-knowledge-check.md)]
14+
quiz:
15+
title: "Check your knowledge"
16+
questions:
17+
- content: "What is the primary purpose of events in C#?"
18+
choices:
19+
- content: "Store data in memory for efficient access during runtime."
20+
isCorrect: false
21+
explanation: "Incorrect. Storing data in memory is not the purpose of events; this is typically handled by variables or collections."
22+
- content: "Define the structure of a class and its methods."
23+
isCorrect: false
24+
explanation: "Incorrect. Defining the structure of a class and its methods is the role of classes and interfaces, not events."
25+
- content: "Enable communication between objects by notifying subscribers when something significant happens."
26+
isCorrect: true
27+
explanation: "Correct. Events allow a publisher to notify subscribers about important occurrences, facilitating interaction between components."
28+
- content: "Which of the following statements correctly describes the relationship between events and delegates in C#?"
29+
choices:
30+
- content: "Events use delegates to define the method signature for event handlers."
31+
isCorrect: true
32+
explanation: "Correct. Delegates provide the type-safe function pointer mechanism that events rely on to define the method signature for event handlers."
33+
- content: "Use delegates only for subscribing to events but not for raising them."
34+
isCorrect: false
35+
explanation: "Incorrect. Delegates are integral to both subscribing to and raising events, as they define the method signature for event handlers."
36+
- content: "Treat events and delegates as unrelated concepts in C# programming."
37+
isCorrect: false
38+
explanation: "Incorrect. Events and delegates are closely related; events are built on the language support for delegates."
39+
- content: "Imagine a developer creates a graphical user interface with a button. The button notifies other components when selected. What should the developer use to implement this functionality?"
40+
choices:
41+
- content: "Use a static method in the button class to directly call methods in other components."
42+
isCorrect: false
43+
explanation: "Incorrect. Using a static method creates tight coupling between components, which goes against the design goals of events."
44+
- content: "Define an event in the button class and allow other components to subscribe to it."
45+
isCorrect: true
46+
explanation: "Correct. Defining an event in the button class allows other components to subscribe and respond to the button select action."
47+
- content: "Create a global variable to store the state of the button and let other components check its value periodically."
48+
isCorrect: false
49+
explanation: "Incorrect. This approach is inefficient and does not provide real-time notification, unlike events."
50+
- content: "Why is unsubscribing from events in C# important?"
51+
choices:
52+
- content: "Prevent the event from being raised multiple times."
53+
isCorrect: false
54+
explanation: "Incorrect. Unsubscribing does not prevent the event from being raised; it only detaches the handler."
55+
- content: "Ensure that the event publisher raises the event without errors."
56+
isCorrect: false
57+
explanation: "Incorrect. Unsubscribing is not required for the publisher to raise the event."
58+
- content: "Avoid memory leaks when the event publisher outlives the subscriber."
59+
isCorrect: true
60+
explanation: "Correct. Failing to unsubscribe leads to memory leaks if the publisher holds a reference to the subscriber longer than necessary."
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.create-manage-events.summary
3+
title: Summary
4+
metadata:
5+
title: Summary
6+
description: "Summarize the key concepts covered in this module."
7+
ms.date: 04/24/2025
8+
author: wwlpublish
9+
ms.author: eric
10+
ms.topic: unit
11+
durationInMinutes: 2
12+
content: |
13+
[!include[](includes/8-summary.md)]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Events in C# are a powerful feature that allows objects to communicate with each other, making it easier to build interactive and dynamic applications.
2+
3+
Imagine you're a developer working on a desktop application for a retail store. The application has a graphical user interface where users can select buttons to add items to a shopping cart, apply discounts, or complete a purchase. Without a proper mechanism to handle these user actions, your code becomes messy and difficult to maintain. Events in C# provide a clean way to manage these interactions. For example, when a 'Checkout' button is clicked, an event can notify the relevant parts of your application to calculate totals, update inventory, and generate receipts. This approach ensures your components work together seamlessly without being tightly connected, making your application more flexible and easier to maintain.
4+
5+
## Learning objectives
6+
7+
- Understand Events and Delegates in C#.
8+
- Examine and Declare Events in C#.
9+
- Encapsulate and Raise Events in C#.
10+
- Manage Event Subscription and Unsubscription in C#.
11+
12+
## Prerequisites
13+
14+
- Visual Studio Code installed with the C# Dev Kit.
15+
- Basic knowledge of the Visual Studio Code IDE.
16+
- Basic understanding of the C# programming language.
17+
- Familiar with classes, abstract classes, interfaces and inheritance.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
As you continue developing the retail store application, your team is eager to improve the way the app responds to user actions like button and menu selections. After setting up basic functionality for actions for adding items to a cart and completing a purchase, it's time to explore how events in C# can streamline these processes.
2+
3+
Events allow different parts of your application to communicate effectively. When users select a button or menu item, events ensure tasks like updating inventory or applying discounts happen smoothly. The use of events not only keeps your code organized but also makes it easier to adapt and expand your application as new features are added. By understanding how events work and their relationship with delegates, you're able to build a more flexible and maintainable application.
4+
5+
## Understand events
6+
7+
Events let one part of a program inform other parts when something important occurs. The part that sends out the event is called the **publisher**, and the parts that respond to the event are called **subscribers**. For instance, events are often used in programs with graphical user interfaces to react to things like button or menu selections.
8+
9+
The following diagram illustrates the relationship between a publisher and subscribers in an event-driven model:
10+
11+
:::image type="content" source="../media/publisher-subscriber.png" alt-text="Diagram showing publisher and subscriber relationship.":::
12+
13+
- The **publisher** raises an event when a specific action occurs, such as the selection of a button.
14+
- The **subscribers** handle the event by executing their respective event handler methods.
15+
16+
This model ensures that the publisher and subscribers remain loosely coupled, allowing for greater flexibility and maintainability.
17+
18+
**Key properties of events**
19+
20+
- Publishers determine when an event is raised, and subscribers decide what action to take in response.
21+
- An event can have multiple subscribers, and a subscriber can handle multiple events.
22+
- Events without subscribers are never raised.
23+
24+
**Example: A simple button click event**
25+
26+
```csharp
27+
public class Button
28+
{
29+
public event EventHandler? Selected; // Nullable to indicate no subscribers initially
30+
31+
public void OnClick()
32+
{
33+
// If subscribers exist, ?.Invoke syntax triggers an event
34+
Selected?.Invoke(this, EventArgs.Empty);
35+
}
36+
}
37+
38+
// Subscribing to the event
39+
Button button = new Button();
40+
button.Selected += (sender, e) => Console.WriteLine("Button Selected!");
41+
42+
// Triggering the event
43+
button.OnClick(); // Output: "Button Selected!"
44+
```
45+
46+
In this example, the `Selected` event is declared as `EventHandler?`, using a nullable reference type which explicitly indicates that the event might not have any subscribers, ensuring that the code handles such scenarios gracefully. The `?.Invoke` syntax further ensures that the event is only raised if there are subscribers, preventing potential `NullReferenceException` errors.
47+
48+
Lambda expressions (`=>`) are used in the subscription to define the event handler inline. Lambda expressions provide a concise and readable way to define event handlers, especially when the logic is simple and doesn't require a separate method.
49+
50+
## Delegates: The foundation of events
51+
52+
Delegates are type-safe function pointers that allow methods to be passed as parameters and invoked dynamically. Events in C# are built on the foundation of delegates, which define the method signature for event handlers.
53+
54+
**How delegates relate to events**:
55+
56+
- Delegates define the method signature that event handlers must match.
57+
- Events use delegates to notify subscribers when something significant occurs.
58+
59+
**Example: Delegate behind an event**
60+
61+
```csharp
62+
// Define a delegate
63+
public delegate void ButtonClickedHandler(object sender, EventArgs e);
64+
65+
// Use the delegate in an event
66+
public class Button
67+
{
68+
public event ButtonClickedHandler Clicked;
69+
70+
public void OnClick()
71+
{
72+
Clicked?.Invoke(this, EventArgs.Empty);
73+
}
74+
}
75+
```
76+
77+
> [!NOTE]
78+
> Delegates provide the type-safe mechanism that events rely on to notify subscribers.
79+
80+
## Events design
81+
82+
The design of events in C# aims to facilitate minimal coupling between components while ensuring flexibility and ease of use.
83+
84+
**Goals of event design**
85+
86+
- **Minimal coupling**: Events enable interaction between an event source and an event sink without requiring tight dependencies. Minimal coupling, using events, is especially useful when components developed by different teams or updated independently.
87+
- **Ease of subscription and unsubscription**: The syntax for subscribing (`+=`) and unsubscribing (`-=`) is straightforward.
88+
- **Support for multiple subscribers**: Events can have zero, one, or multiple subscribers, making them versatile for various scenarios.
89+
90+
Events are often used in scenarios where user actions or system changes need to be communicated across components. For example, a `Closing` event might allow subscribers to cancel the close operation or modify its behavior.

0 commit comments

Comments
 (0)