gestione degli eventi ASP.NET Core Blazor

Nota

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Importante

Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Questo articolo illustra le Blazorfunzionalità di gestione degli eventi, inclusi i tipi di argomento evento, i callback degli eventi e la gestione degli eventi predefiniti del browser.

Delegare i gestori eventi

Specificare i gestori eventi delegati nel Razor markup del componente con @on{DOM EVENT}="{DELEGATE}"Razor la sintassi:

  • Il {DOM EVENT} segnaposto è un evento DOM , ad esempio click.
  • Il {DELEGATE} segnaposto è il gestore eventi del delegato C#.

Per la gestione degli eventi:

  • I gestori eventi delegati asincroni che restituiscono un Task oggetto sono supportati.
  • I gestori eventi delegati attivano automaticamente un rendering dell'interfaccia utente, quindi non è necessario chiamare StateHasChangedmanualmente .
  • Vengono registrate eccezioni.

Il codice seguente:

  • Chiama il UpdateHeading metodo quando il pulsante è selezionato nell'interfaccia utente.
  • Chiama il CheckChanged metodo quando la casella di controllo viene modificata nell'interfaccia utente.

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 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}";
    }
}

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}";
    }
}

Nell'esempio seguente: UpdateHeading

  • Viene chiamato in modo asincrono quando il pulsante è selezionato.
  • Attende due secondi prima di aggiornare l'intestazione.

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})";
    }
}

Argomenti evento predefiniti

Per gli eventi che supportano un tipo di argomento evento, è necessario specificare un parametro di evento nella definizione del metodo evento solo se il tipo di evento viene utilizzato nel metodo . Nell'esempio MouseEventArgs seguente viene usato nel metodo per impostare il ReportPointerLocation testo del messaggio che segnala le coordinate del mouse quando l'utente seleziona un pulsante nell'interfaccia utente.

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}";
    }
}

Le opzioni supportate EventArgs sono illustrate nella tabella seguente.

Event Classe Note DOM
Appunti ClipboardEventArgs
Trascina DragEventArgs DataTransfer e DataTransferItem tenere premuti i dati dell'elemento trascinati.

Implementare il trascinamento della selezione nelle Blazor app usando JS l'interoperabilità con l'API Trascinamento e rilascio HTML.
Error ErrorEventArgs
Event EventArgs EventHandlers contiene attributi per configurare i mapping tra i nomi degli eventi e i tipi di argomento evento.
Focus FocusEventArgs Non include il supporto per relatedTarget.
Input ChangeEventArgs
Tastiera KeyboardEventArgs
Mouse MouseEventArgs
Mouse pointer PointerEventArgs
Rotellina del mouse WheelEventArgs
Avanzamento ProgressEventArgs
Touch TouchEventArgs TouchPoint rappresenta un singolo punto di contatto in un dispositivo sensibile al tocco.

Per ulteriori informazioni, vedi le seguenti risorse:

Argomenti evento personalizzati

Blazor supporta argomenti di evento personalizzati, che consentono di passare dati arbitrari ai gestori eventi .NET con eventi personalizzati.

General configuration

Gli eventi personalizzati con argomenti di evento personalizzati sono in genere abilitati con la procedura seguente.

In JavaScript definire una funzione per la compilazione dell'oggetto argomento evento personalizzato dall'evento di origine:

function eventArgsCreator(event) { 
  return {
    customProperty1: 'any value for property 1',
    customProperty2: event.srcElement.id
  };
}

Il event parametro è un evento DOM (documentazione MDN).

Registrare l'evento personalizzato con il gestore precedente in un inizializzatore JavaScript. Specificare il nome dell'evento del browser appropriato a browserEventName, che per l'esempio illustrato in questa sezione è click relativo alla selezione di un pulsante nell'interfaccia utente.

wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js (il segnaposto è l'ID {PACKAGE ID/ASSEMBLY NAME} del pacchetto o il nome dell'assembly dell'app):

Per un'app Blazor Web:

export function afterWebStarted(blazor) {
  blazor.registerCustomEventType('customevent', {
    browserEventName: 'click',
    createEventArgs: eventArgsCreator
  });
}

Per un'app Blazor Server o Blazor WebAssembly :

export function afterStarted(blazor) {
  blazor.registerCustomEventType('customevent', {
    browserEventName: 'click',
    createEventArgs: eventArgsCreator
  });
}

Nota

La chiamata a registerCustomEventType viene eseguita in uno script una sola volta per evento.

Per la chiamata a registerCustomEventType, usare il blazor parametro (minuscolo b) fornito dall'evento Blazor start. Sebbene la registrazione sia valida quando si usa l'oggetto Blazor (maiuscolo B), l'approccio preferito consiste nell'usare il parametro .

Definire una classe per gli argomenti dell'evento:

namespace BlazorSample.CustomEvents;

public class CustomEventArgs : EventArgs
{
    public string? CustomProperty1 {get; set;}
    public string? CustomProperty2 {get; set;}
}

Collegare l'evento personalizzato con gli argomenti dell'evento aggiungendo un'annotazione [EventHandler] di attributo per l'evento personalizzato:

  • Affinché il compilatore trovi la [EventHandler] classe, deve essere inserita in un file di classe C# (.cs), rendendola una normale classe di primo livello.
  • Contrassegnare la classe public.
  • La classe non richiede membri.
  • La classe deve essere denominata "EventHandlers" per poter essere trovata dal Razor compilatore.
  • Posizionare la classe in uno spazio dei nomi specifico dell'app.
  • Importare lo spazio dei nomi nel Razor componente (.razor) in cui viene usato l'evento.
using Microsoft.AspNetCore.Components;

namespace BlazorSample.CustomEvents;

[EventHandler("oncustomevent", typeof(CustomEventArgs),
    enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
{
}

Registrare il gestore eventi in uno o più elementi HTML. Accedere ai dati passati da JavaScript nel metodo del gestore delegato:

@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;
    }
}

Se l'attributo @oncustomevent non viene riconosciuto da IntelliSense, assicurarsi che il componente o il _Imports.razor file contenga un'istruzione @using per lo spazio dei nomi contenente la EventHandler classe .

Ogni volta che l'evento personalizzato viene generato nel DOM, il gestore eventi viene chiamato con i dati passati da JavaScript.

Se si sta tentando di generare un evento personalizzato, bubbles è necessario abilitare impostandone il valore su true. In caso contrario, l'evento non raggiunge il gestore per l'elaborazione Blazor nella classe di attributi personalizzati [EventHandler] C#. Per altre informazioni, vedere MdN Web Docs: bubbling degli eventi.

Esempio di evento Incolla appunti personalizzato

L'esempio seguente riceve un evento incollato personalizzato degli Appunti che include l'ora della incolla e il testo incollato dell'utente.

Dichiarare un nome personalizzato (oncustompaste) per l'evento e una classe .NET (CustomPasteEventArgs) per contenere gli argomenti dell'evento per questo evento:

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; }
}

Aggiungere codice JavaScript per fornire dati per la EventArgs sottoclasse con il gestore precedente in un inizializzatore JavaScript. L'esempio seguente gestisce solo il incollamento del testo, ma è possibile usare API JavaScript arbitrarie per gestire gli utenti che incollano altri tipi di dati, ad esempio immagini.

wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js:

Per un'app Blazor Web:

export function afterWebStarted(blazor) {
  blazor.registerCustomEventType('custompaste', {
    browserEventName: 'paste',
    createEventArgs: event => {
      return {
        eventTimestamp: new Date(),
        pastedData: event.clipboardData.getData('text')
      };
    }
  });
}

Per un'app Blazor Server o Blazor WebAssembly :

export function afterStarted(blazor) {
  blazor.registerCustomEventType('custompaste', {
    browserEventName: 'paste',
    createEventArgs: event => {
      return {
        eventTimestamp: new Date(),
        pastedData: event.clipboardData.getData('text')
      };
    }
  });
}

Nell'esempio precedente il {PACKAGE ID/ASSEMBLY NAME} segnaposto del nome file rappresenta l'ID pacchetto o il nome dell'assembly dell'app.

Nota

Per la chiamata a registerCustomEventType, usare il blazor parametro (minuscolo b) fornito dall'evento Blazor start. Sebbene la registrazione sia valida quando si usa l'oggetto Blazor (maiuscolo B), l'approccio preferito consiste nell'usare il parametro .

Il codice precedente indica al browser che quando si verifica un evento nativo paste :

  • Generare un custompaste evento.
  • Specificare i dati degli argomenti dell'evento usando la logica personalizzata indicata:

Le convenzioni dei nomi degli eventi differiscono tra .NET e JavaScript:

  • In .NET i nomi degli eventi sono preceduti da "on".
  • In JavaScript i nomi degli eventi non hanno un prefisso.

In un Razor componente collegare il gestore personalizzato a un elemento .

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}";
    }
}

Espressioni lambda

Le espressioni lambda sono supportate come gestore eventi del delegato.

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";
}

Spesso è utile chiudere i valori aggiuntivi usando i parametri del metodo C#, ad esempio quando si esegue l'iterazione su un set di elementi. Nell'esempio seguente vengono creati tre pulsanti, ognuno dei quali chiama UpdateHeading e passa i dati seguenti:

  • Argomento dell'evento (MouseEventArgs) in e.
  • Numero del pulsante in 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 creazione di un numero elevato di delegati di eventi in un ciclo può causare prestazioni di rendering scarse. Per altre informazioni, vedere ASP.NET Procedure consigliate per le prestazioni principaliBlazor.

Evitare di usare una variabile di ciclo direttamente in un'espressione lambda, ad esempio i nell'esempio di ciclo precedente for . In caso contrario, la stessa variabile viene usata da tutte le espressioni lambda, che comporta l'uso dello stesso valore in tutte le espressioni lambda. Acquisire il valore della variabile in una variabile locale. Nell'esempio precedente:

  • La variabile i di ciclo viene assegnata a buttonNumber.
  • buttonNumber viene usato nell'espressione lambda.

In alternativa, usare un foreach ciclo con Enumerable.Range, che non soffre del problema precedente:

@foreach (var buttonNumber in Enumerable.Range(1,3))
{
    <p>
        <button @onclick="@(e => UpdateHeading(e, buttonNumber))">
            Button #@buttonNumber
        </button>
    </p>
}

EventCallback

Uno scenario comune con componenti annidati esegue un metodo in un componente padre quando si verifica un evento del componente figlio. Un onclick evento che si verifica nel componente figlio è un caso d'uso comune. Per esporre gli eventi tra i componenti, usare un oggetto EventCallback. Un componente padre può assegnare un metodo di callback a un componente figlio.EventCallback

Il componente seguente Child illustra come viene configurato il gestore di onclick un pulsante per ricevere un EventCallback delegato dall'oggetto dell'esempio ParentComponent. è EventCallback tipizzato con MouseEventArgs, appropriato per un onclick evento da un dispositivo periferico.

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; }
}

Il Parent componente imposta il metodo (OnClickCallback) ShowMessage dell'elemento EventCallback<TValue> figlio.

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})";
    }
}

Quando il pulsante è selezionato in ChildComponent:

  • Viene chiamato il Parent metodo del ShowMessage componente. message viene aggiornato e visualizzato nel Parent componente.
  • Una chiamata a StateHasChanged non è necessaria nel metodo del callback (ShowMessage). StateHasChanged viene chiamato automaticamente per eseguire il rendering del Parent componente, proprio come il rerendering dei componenti trigger degli eventi figlio nei gestori eventi che vengono eseguiti all'interno dell'elemento figlio. Per altre informazioni, vedere Rendering dei componenti di ASP.NET CoreRazor.

Usare EventCallback e EventCallback<TValue> per la gestione degli eventi e i parametri del componente di associazione.

Preferisce l'oggetto fortemente tipizzato EventCallback<TValue> rispetto EventCallbacka . EventCallback<TValue> fornisce un feedback avanzato sugli errori quando viene usato un tipo inappropriato, guidando gli utenti del componente verso l'implementazione corretta. Analogamente ad altri gestori eventi dell'interfaccia utente, specificare il parametro di evento è facoltativo. Usare EventCallback quando non è presente alcun valore passato al callback.

EventCallback e EventCallback<TValue> consentire delegati asincroni. EventCallback è tipizzato in modo debole e consente di passare qualsiasi argomento di tipo in InvokeAsync(Object). EventCallback<TValue> è fortemente tipizzato e richiede il passaggio di un T argomento in InvokeAsync(T) che è assegnabile a TValue.

Richiamare un oggetto EventCallback o EventCallback<TValue> con InvokeAsync e attendere :Task

await OnClickCallback.InvokeAsync({ARGUMENT});

Nell'esempio precedente il {ARGUMENT} segnaposto è un argomento facoltativo.

Nell'esempio padre-figlio seguente viene illustrata la tecnica .

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 seconda occorrenza del Child2 componente illustra un callback asincrono e il nuovo message2 valore viene assegnato e sottoposto a rendering con un ritardo di due secondi.

Impedisci azioni predefinite

Utilizzare l'attributo @on{DOM EVENT}:preventDefault di direttiva per impedire l'azione predefinita per un evento, in cui il {DOM EVENT} segnaposto è un evento DOM.

Quando si seleziona una chiave in un dispositivo di input e lo stato attivo dell'elemento si trova su una casella di testo, un browser visualizza normalmente il carattere della chiave nella casella di testo. Nell'esempio seguente viene impedito il comportamento predefinito specificando l'attributo della @onkeydown:preventDefault direttiva . Quando lo stato attivo è sull'elemento<input>, il contatore viene incrementato con la sequenza di tasti MAIUSC++. Il + carattere non viene assegnato al <input> valore dell'elemento. Per altre informazioni su keydown, vedere MDN Web Docs: Document: keydown l'evento .

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++;
        }
    }
}

Specificare l'attributo @on{DOM EVENT}:preventDefault senza un valore equivale a @on{DOM EVENT}:preventDefault="true".

Un'espressione è anche un valore consentito dell'attributo . Nell'esempio seguente, shouldPreventDefault è un bool campo impostato su true o false:

<input @onkeydown:preventDefault="shouldPreventDefault" />

...

@code {
    private bool shouldPreventDefault = true;
}

Arrestare la propagazione degli eventi

Usare l'attributo @on{DOM EVENT}:stopPropagation di direttiva per arrestare la propagazione degli eventi all'interno dell'ambito Blazor . {DOM EVENT} è un segnaposto per un evento DOM.

L'effetto stopPropagation dell'attributo di direttiva è limitato all'ambito Blazor e non si estende al DOM HTML. Gli eventi devono essere propagati alla radice DOM HTML prima di Blazor poter agire su di essi. Per impedire la propagazione di eventi DOM HTML, considerare l'approccio seguente:

Nell'esempio seguente, la selezione della casella di controllo impedisce che gli eventi click del secondo elemento figlio <div> vengano propagati all'elemento padre <div>. Poiché gli eventi click propagati generano normalmente il OnSelectParentDiv metodo , selezionando il secondo elemento figlio <div> viene visualizzato il messaggio padre <div> , a meno che non sia selezionata la casella di controllo.

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}";
}

Concentrarsi su un elemento

Chiamare FocusAsync su un riferimento a un elemento per concentrarsi su un elemento nel codice. Nell'esempio seguente selezionare il pulsante per concentrarsi sull'elemento <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();
    }
}