Gestion des événements ASP.NET Core Blazor
Remarque
Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 8 de cet article.
Avertissement
Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la Stratégie de prise en charge de .NET et .NET Core. Pour la version actuelle, consultez la version .NET 8 de cet article.
Important
Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.
Pour la version actuelle, consultez la version .NET 8 de cet article.
Cet article explique les fonctionnalités de gestion des événements de Blazor, notamment les types d’arguments d’événement, les rappels d’événements et la gestion des événements de navigateur par défaut.
Déléguer des gestionnaires d’événements
Spécifiez les gestionnaires d’événements délégués dans le balisage de composant Razor avec la syntaxe @on{DOM EVENT}="{DELEGATE}"
Razor :
- L’espace réservé
{DOM EVENT}
est un événement DOM (par exemple,click
). - L’espace réservé
{DELEGATE}
est le gestionnaire d’événements délégué C#.
Pour la gestion des événements :
- Les gestionnaires d’événements délégués dans les Blazor Web App sont uniquement appelés dans les composants qui adoptent un mode de rendu interactif. Les exemples de cet article supposent que l’application adopte un mode de rendu interactif globalement dans le composant racine de l’application, généralement le composant
App
. Pour plus d’informations, consultez Modes de rendu ASP.NET Core Blazor. - Les gestionnaires d’événements délégués asynchrones qui retournent Task sont pris en charge.
- Les gestionnaires d’événements délégués déclenchent automatiquement un rendu d’interface utilisateur. Il n’est donc pas nécessaire d’appeler manuellement
StateHasChanged
. - Les exceptions sont consignées.
- Les gestionnaires d’événements délégués asynchrones qui retournent Task sont pris en charge.
- Les gestionnaires d’événements délégués déclenchent automatiquement un rendu d’interface utilisateur. Il n’est donc pas nécessaire d’appeler manuellement
StateHasChanged
. - Les exceptions sont consignées.
L'exemple de code suivant :
- Appelle la méthode
UpdateHeading
lorsque le bouton est sélectionné dans l’interface utilisateur. - Appelle la méthode
CheckChanged
lorsque la case à cocher est modifiée dans l’interface utilisateur.
EventHandler1.razor
:
@page "/event-handler-1"
<PageTitle>Event Handler 1</PageTitle>
<h1>Event Handler Example 1</h1>
<h2>@headingValue</h2>
<p>
<button @onclick="UpdateHeading">
Update heading
</button>
</p>
<p>
<label>
<input type="checkbox" @onchange="CheckChanged" />
@checkedMessage
</label>
</p>
@code {
private string headingValue = "Initial heading";
private string checkedMessage = "Not changed yet";
private void UpdateHeading() => headingValue = $"New heading ({DateTime.Now})";
private void CheckChanged() => checkedMessage = $"Last change {DateTime.Now}";
}
EventHandlerExample1.razor
:
@page "/event-handler-1"
<h1>@headingValue</h1>
<p>
<button @onclick="UpdateHeading">
Update heading
</button>
</p>
<p>
<label>
<input type="checkbox" @onchange="CheckChanged" />
@checkedMessage
</label>
</p>
@code {
private string headingValue = "Initial heading";
private string checkedMessage = "Not changed yet";
private void UpdateHeading()
{
headingValue = $"New heading ({DateTime.Now})";
}
private void CheckChanged()
{
checkedMessage = $"Last changed at {DateTime.Now}";
}
}
EventHandlerExample1.razor
:
@page "/event-handler-1"
<h1>@headingValue</h1>
<p>
<button @onclick="UpdateHeading">
Update heading
</button>
</p>
<p>
<label>
<input type="checkbox" @onchange="CheckChanged" />
@checkedMessage
</label>
</p>
@code {
private string headingValue = "Initial heading";
private string checkedMessage = "Not changed yet";
private void UpdateHeading()
{
headingValue = $"New heading ({DateTime.Now})";
}
private void CheckChanged()
{
checkedMessage = $"Last changed at {DateTime.Now}";
}
}
EventHandlerExample1.razor
:
@page "/event-handler-1"
<h1>@headingValue</h1>
<p>
<button @onclick="UpdateHeading">
Update heading
</button>
</p>
<p>
<label>
<input type="checkbox" @onchange="CheckChanged" />
@checkedMessage
</label>
</p>
@code {
private string headingValue = "Initial heading";
private string checkedMessage = "Not changed yet";
private void UpdateHeading()
{
headingValue = $"New heading ({DateTime.Now})";
}
private void CheckChanged()
{
checkedMessage = $"Last changed at {DateTime.Now}";
}
}
EventHandlerExample1.razor
:
@page "/event-handler-1"
<h1>@headingValue</h1>
<p>
<button @onclick="UpdateHeading">
Update heading
</button>
</p>
<p>
<label>
<input type="checkbox" @onchange="CheckChanged" />
@checkedMessage
</label>
</p>
@code {
private string headingValue = "Initial heading";
private string checkedMessage = "Not changed yet";
private void UpdateHeading()
{
headingValue = $"New heading ({DateTime.Now})";
}
private void CheckChanged()
{
checkedMessage = $"Last changed at {DateTime.Now}";
}
}
Dans l’exemple suivant, UpdateHeading
:
- Est appelé de manière asynchrone lorsque le bouton est sélectionné.
- Attend deux secondes avant de mettre à jour le titre.
EventHandler2.razor
:
@page "/event-handler-2"
<PageTitle>Event Handler 2</PageTitle>
<h1>Event Handler Example 2</h1>
<h2>@headingValue</h2>
<p>
<button @onclick="UpdateHeading">
Update heading
</button>
</p>
@code {
private string headingValue = "Initial heading";
private async Task UpdateHeading()
{
await Task.Delay(2000);
headingValue = $"New heading ({DateTime.Now})";
}
}
EventHandlerExample2.razor
:
@page "/event-handler-2"
<h1>@headingValue</h1>
<p>
<button @onclick="UpdateHeading">
Update heading
</button>
</p>
@code {
private string headingValue = "Initial heading";
private async Task UpdateHeading()
{
await Task.Delay(2000);
headingValue = $"New heading ({DateTime.Now})";
}
}
EventHandlerExample2.razor
:
@page "/event-handler-2"
<h1>@headingValue</h1>
<p>
<button @onclick="UpdateHeading">
Update heading
</button>
</p>
@code {
private string headingValue = "Initial heading";
private async Task UpdateHeading()
{
await Task.Delay(2000);
headingValue = $"New heading ({DateTime.Now})";
}
}
EventHandlerExample2.razor
:
@page "/event-handler-2"
<h1>@headingValue</h1>
<p>
<button @onclick="UpdateHeading">
Update heading
</button>
</p>
@code {
private string headingValue = "Initial heading";
private async Task UpdateHeading()
{
await Task.Delay(2000);
headingValue = $"New heading ({DateTime.Now})";
}
}
EventHandlerExample2.razor
:
@page "/event-handler-2"
<h1>@headingValue</h1>
<p>
<button @onclick="UpdateHeading">
Update heading
</button>
</p>
@code {
private string headingValue = "Initial heading";
private async Task UpdateHeading()
{
await Task.Delay(2000);
headingValue = $"New heading ({DateTime.Now})";
}
}
Arguments d’événement intégrés
Pour les événements qui prennent en charge un type d’argument d’événement, la spécification d’un paramètre d’événement dans la définition de méthode d’événement n’est nécessaire que si le type d’événement est utilisé dans la méthode. Dans l’exemple suivant, MouseEventArgs est utilisé dans la méthode ReportPointerLocation
pour définir le texte du message qui signale les coordonnées de la souris lorsque l’utilisateur sélectionne un bouton dans l’interface utilisateur.
EventHandler3.razor
:
@page "/event-handler-3"
<PageTitle>Event Handler 3</PageTitle>
<h1>Event Handler Example 3</h1>
@for (var i = 0; i < 4; i++)
{
<p>
<button @onclick="ReportPointerLocation">
Where's my mouse pointer for this button?
</button>
</p>
}
<p>@mousePointerMessage</p>
@code {
private string? mousePointerMessage;
private void ReportPointerLocation(MouseEventArgs e) =>
mousePointerMessage = $"Mouse coordinates: {e.ScreenX}:{e.ScreenY}";
}
EventHandlerExample3.razor
:
@page "/event-handler-example-3"
@for (var i = 0; i < 4; i++)
{
<p>
<button @onclick="ReportPointerLocation">
Where's my mouse pointer for this button?
</button>
</p>
}
<p>@mousePointerMessage</p>
@code {
private string? mousePointerMessage;
private void ReportPointerLocation(MouseEventArgs e)
{
mousePointerMessage = $"Mouse coordinates: {e.ScreenX}:{e.ScreenY}";
}
}
EventHandlerExample3.razor
:
@page "/event-handler-example-3"
@for (var i = 0; i < 4; i++)
{
<p>
<button @onclick="ReportPointerLocation">
Where's my mouse pointer for this button?
</button>
</p>
}
<p>@mousePointerMessage</p>
@code {
private string? mousePointerMessage;
private void ReportPointerLocation(MouseEventArgs e)
{
mousePointerMessage = $"Mouse coordinates: {e.ScreenX}:{e.ScreenY}";
}
}
EventHandlerExample3.razor
:
@page "/event-handler-example-3"
@for (var i = 0; i < 4; i++)
{
<p>
<button @onclick="ReportPointerLocation">
Where's my mouse pointer for this button?
</button>
</p>
}
<p>@mousePointerMessage</p>
@code {
private string mousePointerMessage;
private void ReportPointerLocation(MouseEventArgs e)
{
mousePointerMessage = $"Mouse coordinates: {e.ScreenX}:{e.ScreenY}";
}
}
EventHandlerExample3.razor
:
@page "/event-handler-example-3"
@for (var i = 0; i < 4; i++)
{
<p>
<button @onclick="ReportPointerLocation">
Where's my mouse pointer for this button?
</button>
</p>
}
<p>@mousePointerMessage</p>
@code {
private string mousePointerMessage;
private void ReportPointerLocation(MouseEventArgs e)
{
mousePointerMessage = $"Mouse coordinates: {e.ScreenX}:{e.ScreenY}";
}
}
Les EventArgs pris en charge sont indiqués dans le tableau suivant.
événement | Classe | Notes DOM |
---|---|---|
Presse-papiers | ClipboardEventArgs | |
Glisser | DragEventArgs | DataTransfer et DataTransferItem contiennent les données de l’élément déplacé. Implémentez le glisser-déplacer dans les applications Blazor à l’aide de l’interopérabilité JS avec l’API glisser-déplacer HTML. |
Error | ErrorEventArgs | |
événement | EventArgs | EventHandlers contient des attributs pour configurer les mappages entre les noms d’événements et les types d’arguments d’événement. |
Focus | FocusEventArgs | N’inclut pas la prise en charge de relatedTarget . |
Entrée | ChangeEventArgs | |
Clavier | KeyboardEventArgs | |
Souris | MouseEventArgs | |
Pointeur de souris | PointerEventArgs | |
Roulette de la souris | WheelEventArgs | |
Progression | ProgressEventArgs | |
Entrées tactiles | TouchEventArgs | TouchPoint représente un point de contact unique sur un appareil tactile. |
Pour plus d'informations, reportez-vous aux ressources suivantes :
Classes
EventArgs
dans la source de référence ASP.NET Core (branche dotnet/aspnetcoremain
)Remarque
Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).
EventHandlers contient des attributs pour configurer les mappages entre les noms d’événements et les types d’arguments d’événement.
Arguments d’événement personnalisés
Blazor prend en charge les arguments d’événements personnalisés, ce qui vous permet de transmettre des données arbitraires aux gestionnaires d’événements .NET avec des événements personnalisés.
Configuration générale
Les événements personnalisés avec des arguments d’événement personnalisés sont généralement activés en procédant comme suit.
En JavaScript, définissez une fonction pour générer l’objet d’argument d’événement personnalisé à partir de l’événement source :
function eventArgsCreator(event) {
return {
customProperty1: 'any value for property 1',
customProperty2: event.srcElement.id
};
}
Le event
paramètre est un événement DOM (documentation MDN).
Inscrivez l’événement personnalisé avec le gestionnaire précédent dans un initialiseur JavaScript. Indiquez le nom d’événement de navigateur approprié à browserEventName
, qui, pour l’exemple indiqué dans cette section, correspond à une sélection de bouton click
dans l’interface utilisateur.
wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js
(l’{PACKAGE ID/ASSEMBLY NAME}
espace réservé est l’ID du package ou le nom de l’assembly de l’application) :
Pour une Blazor Web App :
export function afterWebStarted(blazor) {
blazor.registerCustomEventType('customevent', {
browserEventName: 'click',
createEventArgs: eventArgsCreator
});
}
Pour une application Blazor Server ou Blazor WebAssembly :
export function afterStarted(blazor) {
blazor.registerCustomEventType('customevent', {
browserEventName: 'click',
createEventArgs: eventArgsCreator
});
}
L’appel à registerCustomEventType
n’est effectué dans un script qu’une seule fois par événement.
Pour l’appel à registerCustomEventType
, utilisez le paramètre blazor
(b
(en) minuscules) fourni par l’événement de démarrage Blazor. Bien que l’inscription soit valide lors de l’utilisation de l’objet Blazor
(B
majuscule), l’approche recommandée consiste à utiliser le paramètre.
Le nom d’événement personnalisé, customevent
dans l’exemple précédent, ne doit pas correspondre à un nom d’événement réservé de Blazor. Vous pouvez trouver les noms réservés dans la source des informations de référence sur le framework Blazor (voir les appels à la fonction registerBuiltInEventType
).
Remarque
Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Définissez une classe pour les arguments d’événement :
namespace BlazorSample.CustomEvents;
public class CustomEventArgs : EventArgs
{
public string? CustomProperty1 {get; set;}
public string? CustomProperty2 {get; set;}
}
Reliez l’événement personnalisé avec les arguments de l’événement en ajoutant une annotation d’attribut [EventHandler]
pour l’événement personnalisé :
- Pour que le compilateur recherche la classe
[EventHandler]
, celle-ci doit être placée dans un fichier de classe C# (.cs
), ce qui en fait une classe de niveau supérieur normale. - Marquez la classe comme
public
. - La classe ne nécessite pas de membres.
- La classe doit être appelée «
EventHandlers
» pour être trouvée par le compilateur Razor. - Placez la classe sous un espace de noms spécifique à votre application.
- Importez l’espace de noms dans le composant Razor (
.razor
) où l’événement est utilisé.
using Microsoft.AspNetCore.Components;
namespace BlazorSample.CustomEvents;
[EventHandler("oncustomevent", typeof(CustomEventArgs),
enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
{
}
Inscrivez le gestionnaire d’événements sur un ou plusieurs éléments HTML. Accédez aux données qui ont été transmises à partir de JavaScript dans la méthode de gestionnaire de délégués :
@using BlazorSample.CustomEvents
<button id="buttonId" @oncustomevent="HandleCustomEvent">Handle</button>
@if (!string.IsNullOrEmpty(propVal1) && !string.IsNullOrEmpty(propVal2))
{
<ul>
<li>propVal1: @propVal1</li>
<li>propVal2: @propVal2</li>
</ul>
}
@code
{
private string? propVal1;
private string? propVal2;
private void HandleCustomEvent(CustomEventArgs eventArgs)
{
propVal1 = eventArgs.CustomProperty1;
propVal2 = eventArgs.CustomProperty2;
}
}
Si l’attribut @oncustomevent
n’est pas reconnu par IntelliSense, vérifiez que le composant ou le fichier _Imports.razor
contient une instruction @using
pour l’espace de noms contenant la classe EventHandler
.
Chaque fois que l’événement personnalisé est déclenché sur le DOM, le gestionnaire d’événements est appelé avec les données transmises à partir du JavaScript.
Si vous tentez de déclencher un événement personnalisé, bubbles
doit être activé en définissant sa valeur sur true
. Sinon, l’événement n’atteint pas le gestionnaire Blazor pour le traitement dans la classe d’attributs [EventHandler]
personnalisée de C#. Pour plus d’informations, consultez Documentation web MDN : Propagation des événements.
Exemple d’événement de collage de presse-papiers personnalisé
L’exemple suivant reçoit un événement de collage de presse-papiers personnalisé qui inclut l’heure du collage et le texte collé de l’utilisateur.
Déclarez un nom personnalisé (oncustompaste
) pour l’événement et une classe .NET (CustomPasteEventArgs
) pour contenir les arguments de l’événement pour cet événement :
CustomEvents.cs
:
using Microsoft.AspNetCore.Components;
namespace BlazorSample.CustomEvents;
[EventHandler("oncustompaste", typeof(CustomPasteEventArgs),
enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
{
}
public class CustomPasteEventArgs : EventArgs
{
public DateTime EventTimestamp { get; set; }
public string? PastedData { get; set; }
}
Ajoutez du code JavaScript pour fournir des données pour la sous-classe EventArgs avec le gestionnaire précédent dans un initialiseur JavaScript. L’exemple suivant gère uniquement le collage de texte, mais vous pouvez utiliser des API JavaScript arbitraires pour traiter les utilisateurs collant d’autres types de données, comme des images.
wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js
:
Pour une Blazor Web App :
export function afterWebStarted(blazor) {
blazor.registerCustomEventType('custompaste', {
browserEventName: 'paste',
createEventArgs: event => {
return {
eventTimestamp: new Date(),
pastedData: event.clipboardData.getData('text')
};
}
});
}
Pour une application Blazor Server ou Blazor WebAssembly :
export function afterStarted(blazor) {
blazor.registerCustomEventType('custompaste', {
browserEventName: 'paste',
createEventArgs: event => {
return {
eventTimestamp: new Date(),
pastedData: event.clipboardData.getData('text')
};
}
});
}
Dans l’exemple précédent, l’espace réservé {PACKAGE ID/ASSEMBLY NAME}
du nom de fichier représente l’ID de package ou le nom d’assembly de l’application.
Remarque
Pour l’appel à registerCustomEventType
, utilisez le paramètre blazor
(b
(en) minuscules) fourni par l’événement de démarrage Blazor. Bien que l’inscription soit valide lors de l’utilisation de l’objet Blazor
(B
majuscule), l’approche recommandée consiste à utiliser le paramètre.
Le code précédent indique au navigateur que lorsqu’un événement natif paste
se produit, il doit :
- Déclencher un événement
custompaste
. - Fournir les données des arguments d’événement à l’aide de la logique personnalisée indiquée :
- Pour
eventTimestamp
, créer une date. - Pour
pastedData
, obtenir les données du presse-papiers sous forme de texte. Pour plus d’informations, consultez Documentation web MDN : ClipboardEvent.clipboardData.
- Pour
Les conventions de nom d’événement diffèrent entre .NET et JavaScript :
- Dans .NET, les noms d’événement sont précédés de «
on
». - En JavaScript, les noms d’événement n’ont pas de préfixe.
Dans un composant Razor, attachez le gestionnaire personnalisé à un élément.
CustomPasteArguments.razor
:
@page "/custom-paste-arguments"
@using BlazorSample.CustomEvents
<label>
Try pasting into the following text box:
<input @oncustompaste="HandleCustomPaste" />
</label>
<p>
@message
</p>
@code {
private string? message;
private void HandleCustomPaste(CustomPasteEventArgs eventArgs)
{
message = $"At {eventArgs.EventTimestamp.ToShortTimeString()}, " +
$"you pasted: {eventArgs.PastedData}";
}
}
Expressions lambda
Les expressions lambda sont prises en charge en tant que gestionnaire d’événements délégués.
EventHandler4.razor
:
@page "/event-handler-4"
<PageTitle>Event Handler 4</PageTitle>
<h1>Event Handler Example 4</h1>
<h2>@heading</h2>
<p>
<button @onclick="@(e => heading = "New heading!!!")">
Update heading
</button>
</p>
@code {
private string heading = "Initial heading";
}
EventHandlerExample4.razor
:
@page "/event-handler-example-4"
<h1>@heading</h1>
<p>
<button @onclick="@(e => heading = "New heading!!!")">
Update heading
</button>
</p>
@code {
private string heading = "Initial heading";
}
EventHandlerExample4.razor
:
@page "/event-handler-example-4"
<h1>@heading</h1>
<p>
<button @onclick="@(e => heading = "New heading!!!")">
Update heading
</button>
</p>
@code {
private string heading = "Initial heading";
}
EventHandlerExample4.razor
:
@page "/event-handler-example-4"
<h1>@heading</h1>
<p>
<button @onclick="@(e => heading = "New heading!!!")">
Update heading
</button>
</p>
@code {
private string heading = "Initial heading";
}
EventHandlerExample4.razor
:
@page "/event-handler-example-4"
<h1>@heading</h1>
<p>
<button @onclick="@(e => heading = "New heading!!!")">
Update heading
</button>
</p>
@code {
private string heading = "Initial heading";
}
Il est souvent pratique de fermer avec des valeurs supplémentaires à l’aide de paramètres de méthode C#, par exemple lors de l’itération sur un ensemble d’éléments. L’exemple suivant crée trois boutons ; chacun d’entre eux appelle UpdateHeading
et transmet les données suivantes :
- Argument d’événement (MouseEventArgs) dans
e
. - Numéro de bouton dans
buttonNumber
.
EventHandler5.razor
:
@page "/event-handler-5"
<PageTitle>Event Handler 5</PageTitle>
<h1>Event Handler Example 5</h1>
<h2>@heading</h2>
@for (var i = 1; i < 4; i++)
{
var buttonNumber = i;
<p>
<button @onclick="@(e => UpdateHeading(e, buttonNumber))">
Button #@i
</button>
</p>
}
@code {
private string heading = "Select a button to learn its position";
private void UpdateHeading(MouseEventArgs e, int buttonNumber) =>
heading = $"Selected #{buttonNumber} at {e.ClientX}:{e.ClientY}";
}
EventHandlerExample5.razor
:
@page "/event-handler-example-5"
<h1>@heading</h1>
@for (var i = 1; i < 4; i++)
{
var buttonNumber = i;
<p>
<button @onclick="@(e => UpdateHeading(e, buttonNumber))">
Button #@i
</button>
</p>
}
@code {
private string heading = "Select a button to learn its position";
private void UpdateHeading(MouseEventArgs e, int buttonNumber)
{
heading = $"Selected #{buttonNumber} at {e.ClientX}:{e.ClientY}";
}
}
EventHandlerExample5.razor
:
@page "/event-handler-example-5"
<h1>@heading</h1>
@for (var i = 1; i < 4; i++)
{
var buttonNumber = i;
<p>
<button @onclick="@(e => UpdateHeading(e, buttonNumber))">
Button #@i
</button>
</p>
}
@code {
private string heading = "Select a button to learn its position";
private void UpdateHeading(MouseEventArgs e, int buttonNumber)
{
heading = $"Selected #{buttonNumber} at {e.ClientX}:{e.ClientY}";
}
}
EventHandlerExample5.razor
:
@page "/event-handler-example-5"
<h1>@heading</h1>
@for (var i = 1; i < 4; i++)
{
var buttonNumber = i;
<p>
<button @onclick="@(e => UpdateHeading(e, buttonNumber))">
Button #@i
</button>
</p>
}
@code {
private string heading = "Select a button to learn its position";
private void UpdateHeading(MouseEventArgs e, int buttonNumber)
{
heading = $"Selected #{buttonNumber} at {e.ClientX}:{e.ClientY}";
}
}
EventHandlerExample5.razor
:
@page "/event-handler-example-5"
<h1>@heading</h1>
@for (var i = 1; i < 4; i++)
{
var buttonNumber = i;
<p>
<button @onclick="@(e => UpdateHeading(e, buttonNumber))">
Button #@i
</button>
</p>
}
@code {
private string heading = "Select a button to learn its position";
private void UpdateHeading(MouseEventArgs e, int buttonNumber)
{
heading = $"Selected #{buttonNumber} at {e.ClientX}:{e.ClientY}";
}
}
La création d’un grand nombre de délégués d’événements dans une boucle peut entraîner des performances de rendu médiocres. Pour plus d’informations, consultez Bonnes pratiques relatives aux performances d’ASP.NET Core Blazor.
Évitez d’utiliser une variable de boucle directement dans une expression lambda, comme i
dans l’exemple de boucle for
précédent. Sinon, la même variable est utilisée par toutes les expressions lambda, ce qui entraîne l’utilisation de la même valeur dans toutes les expressions lambda. Capturez la valeur de la variable dans une variable locale. Dans l'exemple précédent :
- La variable de boucle
i
est affectée àbuttonNumber
. buttonNumber
est utilisé dans l’expression lambda.
Vous pouvez également utiliser une boucle foreach
avec Enumerable.Range, qui ne souffre pas du problème précédent :
@foreach (var buttonNumber in Enumerable.Range(1, 3))
{
<p>
<button @onclick="@(e => UpdateHeading(e, buttonNumber))">
Button #@buttonNumber
</button>
</p>
}
EventCallback
Un scénario courant avec les composants imbriqués exécute une méthode dans un composant parent lorsqu’un événement de composant enfant se produit. Un événement onclick
se produisant dans le composant enfant est un cas d’usage courant. Pour exposer des événements entre les composants, utilisez un EventCallback. Un composant parent peut affecter une méthode de rappel au EventCallback d’un composant enfant.
Le composant Child
suivant montre comment le gestionnaire de onclick
d’un bouton est configuré pour recevoir un délégué EventCallback du ParentComponent
de l’exemple. Le EventCallback est typé avec MouseEventArgs, qui convient à un événement onclick
à partir d’un périphérique.
Child.razor
:
<p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
</p>
@code {
[Parameter]
public string? Title { get; set; }
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
</p>
@code {
[Parameter]
public string? Title { get; set; }
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
</p>
@code {
[Parameter]
public string? Title { get; set; }
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
</p>
@code {
[Parameter]
public string Title { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<p>
<button @onclick="OnClickCallback">
Trigger a Parent component method
</button>
</p>
@code {
[Parameter]
public string Title { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
Le composant Parent
définit le EventCallback<TValue> (OnClickCallback
) de l’enfant sur sa méthode ShowMessage
.
ParentChild.razor
:
@page "/parent-child"
<PageTitle>Parent Child</PageTitle>
<h1>Parent Child Example</h1>
<Child Title="Panel Title from Parent" OnClickCallback="ShowMessage">
Content of the child component is supplied by the parent component.
</Child>
<p>@message</p>
@code {
private string? message;
private void ShowMessage(MouseEventArgs e) =>
message = $"Blaze a new trail with Blazor! ({e.ScreenX}:{e.ScreenY})";
}
Parent.razor
:
@page "/parent"
<h1>Parent-child example</h1>
<Child Title="Panel Title from Parent" OnClickCallback="ShowMessage">
Content of the child component is supplied by the parent component.
</Child>
<p>@message</p>
@code {
private string? message;
private void ShowMessage(MouseEventArgs e)
{
message = $"Blaze a new trail with Blazor! ({e.ScreenX}:{e.ScreenY})";
}
}
Parent.razor
:
@page "/parent"
<h1>Parent-child example</h1>
<Child Title="Panel Title from Parent" OnClickCallback="ShowMessage">
Content of the child component is supplied by the parent component.
</Child>
<p>@message</p>
@code {
private string? message;
private void ShowMessage(MouseEventArgs e)
{
message = $"Blaze a new trail with Blazor! ({e.ScreenX}:{e.ScreenY})";
}
}
Parent.razor
:
@page "/parent"
<h1>Parent-child example</h1>
<Child Title="Panel Title from Parent" OnClickCallback="ShowMessage">
Content of the child component is supplied by the parent component.
</Child>
<p>@message</p>
@code {
private string message;
private void ShowMessage(MouseEventArgs e)
{
message = $"Blaze a new trail with Blazor! ({e.ScreenX}:{e.ScreenY})";
}
}
Parent.razor
:
@page "/parent"
<h1>Parent-child example</h1>
<Child Title="Panel Title from Parent" OnClickCallback="ShowMessage">
Content of the child component is supplied by the parent component.
</Child>
<p>@message</p>
@code {
private string message;
private void ShowMessage(MouseEventArgs e)
{
message = $"Blaze a new trail with Blazor! ({e.ScreenX}:{e.ScreenY})";
}
}
Lorsque le bouton est sélectionné dans le ChildComponent
:
- La méthode
ShowMessage
du composantParent
est appelée.message
est mis à jour et affiché dans le composantParent
. - Un appel à
StateHasChanged
n’est pas requis dans la méthode du rappel (ShowMessage
). StateHasChanged est appelé automatiquement pour renvoyer le composantParent
, tout comme les événements enfants déclenchent une nouvelle génération de composant dans les gestionnaires d’événements qui s’exécutent dans l’enfant. Pour plus d’informations, consultez le rendu de composants Razor ASP.NET Core.
Utilisez EventCallback et EventCallback<TValue> pour la gestion des événements et les paramètres de composant de liaison.
Préférez le EventCallback<TValue> fortement typé à EventCallback. EventCallback<TValue> fournit des commentaires améliorés sur l’erreur lorsqu’un type inapproprié est utilisé, guidant les utilisateurs du composant vers une implémentation appropriée. Comme pour d’autres gestionnaires d’événements d’interface utilisateur, la spécification du paramètre d’événement est facultative. Utilisez EventCallback lorsqu’aucune valeur n’est passée au rappel.
EventCallback et EventCallback<TValue> autorisent les délégués asynchrones. EventCallback est faiblement typé et permet de passer n’importe quel type d’argument dans InvokeAsync(Object)
. EventCallback<TValue> est fortement typé et nécessite de passer un argument T
dans InvokeAsync(T)
qui est assignable à TValue
.
Appelez un EventCallback ou EventCallback<TValue> avec InvokeAsync et attendez Task :
await OnClickCallback.InvokeAsync({ARGUMENT});
Dans l’exemple précédent, l’espace réservé {ARGUMENT}
est un argument facultatif.
L’exemple parent-enfant suivant montre la technique.
Child2.razor
:
<h3>Child2 Component</h3>
<button @onclick="TriggerEvent">Click Me</button>
@code {
[Parameter]
public EventCallback<string> OnClickCallback { get; set; }
private async Task TriggerEvent()
{
await OnClickCallback.InvokeAsync("Blaze It!");
}
}
ParentChild2.razor
:
@page "/parent-child-2"
<PageTitle>Parent Child 2</PageTitle>
<h1>Parent Child 2 Example</h1>
<div>
<Child2 OnClickCallback="(value) => { message1 = value; }" />
@message1
</div>
<div>
<Child2 OnClickCallback=
"async (value) => { await Task.Delay(2000); message2 = value; }" />
@message2
</div>
@code {
private string message1 = string.Empty;
private string message2 = string.Empty;
}
La deuxième occurrence du composant Child2
illustre un appel asynchrone, mais également la nouvelle valeur message2
est affectée et rendue avec un délai de deux secondes.
Empêcher les actions par défaut
Utilisez l’attribut de directive @on{DOM EVENT}:preventDefault
pour empêcher l’action par défaut d’un événement, où l’espace réservé {DOM EVENT}
est un événement DOM (Document Object Model).
Lorsqu’une touche est sélectionnée sur un périphérique d’entrée et que le focus d’élément se trouve sur une zone de texte, un navigateur affiche normalement le caractère de la touche dans la zone de texte. Dans l’exemple suivant, le comportement par défaut est empêché en spécifiant l’attribut de directive @onkeydown:preventDefault
. Lorsque le focus se trouve sur l’élément <input>
, le compteur s’incrémente avec la séquence de touches Maj++. Le caractère +
n’est pas affecté à la valeur de l’élément <input>
. Pour plus d’informations sur keydown
, consultez l’événement MDN Web Docs: Document: keydown
.
EventHandler6.razor
:
@page "/event-handler-6"
<PageTitle>Event Handler 6</PageTitle>
<h1>Event Handler Example 6</h1>
<p>For this example, give the <code><input></code> focus.</p>
<p>
<label>
Count of '+' key presses:
<input value="@count" @onkeydown="KeyHandler" @onkeydown:preventDefault />
</label>
</p>
@code {
private int count = 0;
private void KeyHandler(KeyboardEventArgs e)
{
if (e.Key == "+")
{
count++;
}
}
}
EventHandlerExample6.razor
:
@page "/event-handler-example-6"
<p>
<input value="@count" @onkeydown="KeyHandler" @onkeydown:preventDefault />
</p>
@code {
private int count = 0;
private void KeyHandler(KeyboardEventArgs e)
{
if (e.Key == "+")
{
count++;
}
}
}
EventHandlerExample6.razor
:
@page "/event-handler-example-6"
<p>
<input value="@count" @onkeydown="KeyHandler" @onkeydown:preventDefault />
</p>
@code {
private int count = 0;
private void KeyHandler(KeyboardEventArgs e)
{
if (e.Key == "+")
{
count++;
}
}
}
EventHandlerExample6.razor
:
@page "/event-handler-example-6"
<p>
<input value="@count" @onkeydown="KeyHandler" @onkeydown:preventDefault />
</p>
@code {
private int count = 0;
private void KeyHandler(KeyboardEventArgs e)
{
if (e.Key == "+")
{
count++;
}
}
}
EventHandlerExample6.razor
:
@page "/event-handler-example-6"
<p>
<input value="@count" @onkeydown="KeyHandler" @onkeydown:preventDefault />
</p>
@code {
private int count = 0;
private void KeyHandler(KeyboardEventArgs e)
{
if (e.Key == "+")
{
count++;
}
}
}
La spécification de l’attribut @on{DOM EVENT}:preventDefault
sans valeur équivaut à @on{DOM EVENT}:preventDefault="true"
.
Une expression est également une valeur autorisée de l’attribut. Dans l’exemple suivant, shouldPreventDefault
est un champ bool
défini sur true
ou false
:
<input @onkeydown:preventDefault="shouldPreventDefault" />
...
@code {
private bool shouldPreventDefault = true;
}
Arrêter la propagation d’événements
Utilisez l’attribut de directive @on{DOM EVENT}:stopPropagation
pour arrêter la propagation d’événements dans l’étendue Blazor. {DOM EVENT}
est un espace réservé pour un événement DOM.
L’effet de l’attribut de directive stopPropagation
est limité à l’étendue Blazor et ne s’étend pas au DOM HTML. Les événements doivent se propager à la racine DOM HTML avant que Blazor puisse agir dessus. Pour qu’un mécanisme empêche la propagation d’événements DOM HTML, envisagez l’approche suivante :
- Obtenez le chemin d’accès de l’événement en appelant
Event.composedPath()
. - Filtrez les événements en fonction des cibles d’événement composées (
EventTarget
).
Dans l’exemple suivant, la case à cocher empêche les événements de clic du deuxième <div>
enfant de se propager au <div>
parent. Étant donné que les événements de clic propagés déclenchent normalement la méthode OnSelectParentDiv
, la sélection du deuxième <div>
enfant entraîne l’affichage du message parent <div>
, sauf si la case est cochée.
EventHandler7.razor
:
@page "/event-handler-7"
<PageTitle>Event Handler 7</PageTitle>
<h1>Event Handler Example 7</h1>
<div>
<b>stopPropagation</b>: @stopPropagation
</div>
<div>
<button @onclick="StopPropagation">
Stop Propagation (stopPropagation = true)
</button>
<button @onclick="EnablePropagation">
Enable Propagation (stopPropagation = false)
</button>
</div>
<div class="m-1 p-1 border border-primary" @onclick="OnSelectParentDiv">
<h3>Parent div</h3>
<div class="m-1 p-1 border" @onclick="OnSelectChildDiv">
Child div that never stops propagation to the parent div when
selected.
</div>
<div class="m-1 p-1 border" @onclick="OnSelectChildDiv"
@onclick:stopPropagation="stopPropagation">
Child div that stops propagation when selected if
<b>stopPropagation</b> is <b>true</b>.
</div>
</div>
<p>
@message
</p>
@code {
private bool stopPropagation = false;
private string? message;
private void StopPropagation() => stopPropagation = true;
private void EnablePropagation() => stopPropagation = false;
private void OnSelectParentDiv() =>
message = $"The parent div was selected. {DateTime.Now}";
private void OnSelectChildDiv() =>
message = $"The child div was selected. {DateTime.Now}";
}
EventHandlerExample7.razor
:
@page "/event-handler-example-7"
<div>
<b>stopPropagation</b>: @stopPropagation
</div>
<div>
<button @onclick="StopPropagation">
Stop Propagation (stopPropagation = true)
</button>
<button @onclick="EnablePropagation">
Enable Propagation (stopPropagation = false)
</button>
</div>
<div class="m-1 p-1 border border-primary" @onclick="OnSelectParentDiv">
<h3>Parent div</h3>
<div class="m-1 p-1 border" @onclick="OnSelectChildDiv">
Child div that never stops propagation to the parent div when
selected.
</div>
<div class="m-1 p-1 border" @onclick="OnSelectChildDiv"
@onclick:stopPropagation="stopPropagation">
Child div that stops propagation when selected if
<b>stopPropagation</b> is <b>true</b>.
</div>
</div>
<p>
@message
</p>
@code {
private bool stopPropagation = false;
private string? message;
private void StopPropagation() => stopPropagation = true;
private void EnablePropagation() => stopPropagation = false;
private void OnSelectParentDiv() =>
message = $"The parent div was selected. {DateTime.Now}";
private void OnSelectChildDiv() =>
message = $"The child div was selected. {DateTime.Now}";
}
EventHandlerExample7.razor
:
@page "/event-handler-example-7"
<div>
<b>stopPropagation</b>: @stopPropagation
</div>
<div>
<button @onclick="StopPropagation">
Stop Propagation (stopPropagation = true)
</button>
<button @onclick="EnablePropagation">
Enable Propagation (stopPropagation = false)
</button>
</div>
<div class="m-1 p-1 border border-primary" @onclick="OnSelectParentDiv">
<h3>Parent div</h3>
<div class="m-1 p-1 border" @onclick="OnSelectChildDiv">
Child div that never stops propagation to the parent div when
selected.
</div>
<div class="m-1 p-1 border" @onclick="OnSelectChildDiv"
@onclick:stopPropagation="stopPropagation">
Child div that stops propagation when selected if
<b>stopPropagation</b> is <b>true</b>.
</div>
</div>
<p>
@message
</p>
@code {
private bool stopPropagation = false;
private string? message;
private void StopPropagation() => stopPropagation = true;
private void EnablePropagation() => stopPropagation = false;
private void OnSelectParentDiv() =>
message = $"The parent div was selected. {DateTime.Now}";
private void OnSelectChildDiv() =>
message = $"The child div was selected. {DateTime.Now}";
}
EventHandlerExample7.razor
:
@page "/event-handler-example-7"
<div>
<b>stopPropagation</b>: @stopPropagation
</div>
<div>
<button @onclick="StopPropagation">
Stop Propagation (stopPropagation = true)
</button>
<button @onclick="EnablePropagation">
Enable Propagation (stopPropagation = false)
</button>
</div>
<div class="m-1 p-1 border border-primary" @onclick="OnSelectParentDiv">
<h3>Parent div</h3>
<div class="m-1 p-1 border" @onclick="OnSelectChildDiv">
Child div that never stops propagation to the parent div when
selected.
</div>
<div class="m-1 p-1 border" @onclick="OnSelectChildDiv"
@onclick:stopPropagation="stopPropagation">
Child div that stops propagation when selected if
<b>stopPropagation</b> is <b>true</b>.
</div>
</div>
<p>
@message
</p>
@code {
private bool stopPropagation = false;
private string message;
private void StopPropagation() => stopPropagation = true;
private void EnablePropagation() => stopPropagation = false;
private void OnSelectParentDiv() =>
message = $"The parent div was selected. {DateTime.Now}";
private void OnSelectChildDiv() =>
message = $"The child div was selected. {DateTime.Now}";
}
EventHandlerExample7.razor
:
@page "/event-handler-example-7"
<div>
<b>stopPropagation</b>: @stopPropagation
</div>
<div>
<button @onclick="StopPropagation">
Stop Propagation (stopPropagation = true)
</button>
<button @onclick="EnablePropagation">
Enable Propagation (stopPropagation = false)
</button>
</div>
<div class="m-1 p-1 border border-primary" @onclick="OnSelectParentDiv">
<h3>Parent div</h3>
<div class="m-1 p-1 border" @onclick="OnSelectChildDiv">
Child div that never stops propagation to the parent div when
selected.
</div>
<div class="m-1 p-1 border" @onclick="OnSelectChildDiv"
@onclick:stopPropagation="stopPropagation">
Child div that stops propagation when selected if
<b>stopPropagation</b> is <b>true</b>.
</div>
</div>
<p>
@message
</p>
@code {
private bool stopPropagation = false;
private string message;
private void StopPropagation() => stopPropagation = true;
private void EnablePropagation() => stopPropagation = false;
private void OnSelectParentDiv() =>
message = $"The parent div was selected. {DateTime.Now}";
private void OnSelectChildDiv() =>
message = $"The child div was selected. {DateTime.Now}";
}
Focus sur un élément
Appelez FocusAsync sur une référence d’élément pour placer le focus sur un élément dans le code. Dans l’exemple suivant, sélectionnez le bouton pour placer le focus sur l’élément <input>
.
EventHandler8.razor
:
@page "/event-handler-8"
<PageTitle>Event Handler 8</PageTitle>
<h1>Event Handler Example 8</h1>
<p>Select the button to give the <code><input></code> focus.</p>
<p>
<label>
Input:
<input @ref="exampleInput" />
</label>
</p>
<button @onclick="ChangeFocus">
Focus the Input Element
</button>
@code {
private ElementReference exampleInput;
private async Task ChangeFocus()
{
await exampleInput.FocusAsync();
}
}
EventHandlerExample8.razor
:
@page "/event-handler-example-8"
<p>
<input @ref="exampleInput" />
</p>
<button @onclick="ChangeFocus">
Focus the Input Element
</button>
@code {
private ElementReference exampleInput;
private async Task ChangeFocus()
{
await exampleInput.FocusAsync();
}
}
EventHandlerExample8.razor
:
@page "/event-handler-example-8"
<p>
<input @ref="exampleInput" />
</p>
<button @onclick="ChangeFocus">
Focus the Input Element
</button>
@code {
private ElementReference exampleInput;
private async Task ChangeFocus()
{
await exampleInput.FocusAsync();
}
}