Обработка событий Blazor в ASP.NET CoreASP.NET Core Blazor event handling

Авторы: Люк Латэм (Luke Latham) и Дэниэл Рот (Daniel Roth)By Luke Latham and Daniel Roth

Компоненты Razor предоставляют функции обработки событий.Razor components provide event handling features. Для атрибута HTML-элемента с именем @on{EVENT} (например, @onclick) и значением типа делегата компонент Razor рассматривает значение атрибута как обработчик событий.For an HTML element attribute named @on{EVENT} (for example, @onclick) with a delegate-typed value, a Razor component treats the attribute's value as an event handler.

Следующий код вызывает метод UpdateHeading, когда в пользовательском интерфейсе выбрана кнопка:The following code calls the UpdateHeading method when the button is selected in the UI:

<button class="btn btn-primary" @onclick="UpdateHeading">
    Update heading
</button>

@code {
    private void UpdateHeading(MouseEventArgs e)
    {
        ...
    }
}

Следующий код вызывает метод CheckChanged, когда в пользовательском интерфейсе установлен флажок:The following code calls the CheckChanged method when the check box is changed in the UI:

<input type="checkbox" class="form-check-input" @onchange="CheckChanged" />

@code {
    private void CheckChanged()
    {
        ...
    }
}

Обработчики событий также могут быть асинхронными и возвращать Task.Event handlers can also be asynchronous and return a Task. Нет необходимости вручную вызывать StateHasChanged.There's no need to manually call StateHasChanged. Исключения регистрируются при их возникновении.Exceptions are logged when they occur.

В следующем примере UpdateHeading вызывается асинхронно при выборе кнопки:In the following example, UpdateHeading is called asynchronously when the button is selected:

<button class="btn btn-primary" @onclick="UpdateHeading">
    Update heading
</button>

@code {
    private async Task UpdateHeading(MouseEventArgs e)
    {
        await ...
    }
}

Типы аргументов событийEvent argument types

Для некоторых событий разрешены типы аргументов событий.For some events, event argument types are permitted. Указание параметра события в определении метода события является необязательным и требуется только в том случае, если тип события используется в методе.Specifying an event parameter in an event method definition is optional and only necessary if the event type is used in the method. В следующем примере аргумент события MouseEventArgs используется в методе ShowMessage для задания текста сообщения:In the following example, the MouseEventArgs event argument is used in the ShowMessage method to set message text:

private void ShowMessage(MouseEventArgs e)
{
    messageText = $"The mouse is at coordinates: {e.ScreenX}:{e.ScreenY}";
}

Поддерживаемые параметры EventArgs приведены в следующей таблице.Supported EventArgs are shown in the following table.

СобытиеEvent ClassClass События DOM и примечанияDOM events and notes
Буфер обменаClipboard ClipboardEventArgs oncut, oncopy, onpasteoncut, oncopy, onpaste
ПеретаскиваниеDrag DragEventArgs ondrag, ondragstart, ondragenter, ondragleave, ondragover, ondrop, ondragendondrag, ondragstart, ondragenter, ondragleave, ondragover, ondrop, ondragend

DataTransfer и DataTransferItem содержат данные перетаскиваемого элемента.DataTransfer and DataTransferItem hold dragged item data.

Реализуйте перетаскивание в приложениях Blazor с помощью взаимодействия JS с API перетаскивания для HTML.Implement drag and drop in Blazor apps using JS interop with HTML Drag and Drop API.
ErrorError ErrorEventArgs onerror
СобытиеEvent EventArgs Общие сведенияGeneral
onactivate, onbeforeactivate, onbeforedeactivate, ondeactivate, onfullscreenchange, onfullscreenerror, onloadeddata, onloadedmetadata, onpointerlockchange, onpointerlockerror, onreadystatechange, onscrollonactivate, onbeforeactivate, onbeforedeactivate, ondeactivate, onfullscreenchange, onfullscreenerror, onloadeddata, onloadedmetadata, onpointerlockchange, onpointerlockerror, onreadystatechange, onscroll

Буфер обменаClipboard
onbeforecut, onbeforecopy, onbeforepasteonbeforecut, onbeforecopy, onbeforepaste

ВводInput
oninvalid, onreset, onselect, onselectionchange, onselectstart, onsubmitoninvalid, onreset, onselect, onselectionchange, onselectstart, onsubmit

НосительMedia
oncanplay, oncanplaythrough, oncuechange, ondurationchange, onemptied, onended, onpause, onplay, onplaying, onratechange, onseeked, onseeking, onstalled, onstop, onsuspend, ontimeupdate, ontoggle, onvolumechange, onwaitingoncanplay, oncanplaythrough, oncuechange, ondurationchange, onemptied, onended, onpause, onplay, onplaying, onratechange, onseeked, onseeking, onstalled, onstop, onsuspend, ontimeupdate, ontoggle, onvolumechange, onwaiting

EventHandlers содержит атрибуты для настройки сопоставлений между именами событий и типами аргументов событий.EventHandlers holds attributes to configure the mappings between event names and event argument types.
ФокусFocus FocusEventArgs onfocus, onblur, onfocusin, onfocusoutonfocus, onblur, onfocusin, onfocusout

Не включает поддержку relatedTarget.Doesn't include support for relatedTarget.
Входные данныеInput ChangeEventArgs onchange, oninputonchange, oninput
КлавиатураKeyboard KeyboardEventArgs onkeydown, onkeypress, onkeyuponkeydown, onkeypress, onkeyup
МышьMouse MouseEventArgs onclick, oncontextmenu, ondblclick, onmousedown, onmouseup, onmouseover, onmousemove, onmouseoutonclick, oncontextmenu, ondblclick, onmousedown, onmouseup, onmouseover, onmousemove, onmouseout
Указатель мышиMouse pointer PointerEventArgs onpointerdown, onpointerup, onpointercancel, onpointermove, onpointerover, onpointerout, onpointerenter, onpointerleave, ongotpointercapture, onlostpointercaptureonpointerdown, onpointerup, onpointercancel, onpointermove, onpointerover, onpointerout, onpointerenter, onpointerleave, ongotpointercapture, onlostpointercapture
Колесико мышиMouse wheel WheelEventArgs onwheel, onmousewheelonwheel, onmousewheel
Ход выполненияProgress ProgressEventArgs onabort, onload, onloadend, onloadstart, onprogress, ontimeoutonabort, onload, onloadend, onloadstart, onprogress, ontimeout
Сенсорные технологииTouch TouchEventArgs ontouchstart, ontouchend, ontouchmove, ontouchenter, ontouchleave, ontouchcancelontouchstart, ontouchend, ontouchmove, ontouchenter, ontouchleave, ontouchcancel

TouchPoint представляет одну точку касания на устройстве с сенсорным вводом.TouchPoint represents a single contact point on a touch-sensitive device.
СобытиеEvent ClassClass События DOM и примечанияDOM events and notes
Буфер обменаClipboard ClipboardEventArgs oncut, oncopy, onpasteoncut, oncopy, onpaste
ПеретаскиваниеDrag DragEventArgs ondrag, ondragstart, ondragenter, ondragleave, ondragover, ondrop, ondragendondrag, ondragstart, ondragenter, ondragleave, ondragover, ondrop, ondragend

DataTransfer и DataTransferItem содержат данные перетаскиваемого элемента.DataTransfer and DataTransferItem hold dragged item data.

Реализуйте перетаскивание в приложениях Blazor с помощью взаимодействия JS с API перетаскивания для HTML.Implement drag and drop in Blazor apps using JS interop with HTML Drag and Drop API.
ErrorError ErrorEventArgs onerror
СобытиеEvent EventArgs Общие сведенияGeneral
onactivate, onbeforeactivate, onbeforedeactivate, ondeactivate, onfullscreenchange, onfullscreenerror, onloadeddata, onloadedmetadata, onpointerlockchange, onpointerlockerror, onreadystatechange, onscrollonactivate, onbeforeactivate, onbeforedeactivate, ondeactivate, onfullscreenchange, onfullscreenerror, onloadeddata, onloadedmetadata, onpointerlockchange, onpointerlockerror, onreadystatechange, onscroll

Буфер обменаClipboard
onbeforecut, onbeforecopy, onbeforepasteonbeforecut, onbeforecopy, onbeforepaste

ВводInput
oninvalid, onreset, onselect, onselectionchange, onselectstart, onsubmitoninvalid, onreset, onselect, onselectionchange, onselectstart, onsubmit

НосительMedia
oncanplay, oncanplaythrough, oncuechange, ondurationchange, onemptied, onended, onpause, onplay, onplaying, onratechange, onseeked, onseeking, onstalled, onstop, onsuspend, ontimeupdate, onvolumechange, onwaitingoncanplay, oncanplaythrough, oncuechange, ondurationchange, onemptied, onended, onpause, onplay, onplaying, onratechange, onseeked, onseeking, onstalled, onstop, onsuspend, ontimeupdate, onvolumechange, onwaiting

EventHandlers содержит атрибуты для настройки сопоставлений между именами событий и типами аргументов событий.EventHandlers holds attributes to configure the mappings between event names and event argument types.
ФокусFocus FocusEventArgs onfocus, onblur, onfocusin, onfocusoutonfocus, onblur, onfocusin, onfocusout

Не включает поддержку relatedTarget.Doesn't include support for relatedTarget.
Входные данныеInput ChangeEventArgs onchange, oninputonchange, oninput
КлавиатураKeyboard KeyboardEventArgs onkeydown, onkeypress, onkeyuponkeydown, onkeypress, onkeyup
МышьMouse MouseEventArgs onclick, oncontextmenu, ondblclick, onmousedown, onmouseup, onmouseover, onmousemove, onmouseoutonclick, oncontextmenu, ondblclick, onmousedown, onmouseup, onmouseover, onmousemove, onmouseout
Указатель мышиMouse pointer PointerEventArgs onpointerdown, onpointerup, onpointercancel, onpointermove, onpointerover, onpointerout, onpointerenter, onpointerleave, ongotpointercapture, onlostpointercaptureonpointerdown, onpointerup, onpointercancel, onpointermove, onpointerover, onpointerout, onpointerenter, onpointerleave, ongotpointercapture, onlostpointercapture
Колесико мышиMouse wheel WheelEventArgs onwheel, onmousewheelonwheel, onmousewheel
Ход выполненияProgress ProgressEventArgs onabort, onload, onloadend, onloadstart, onprogress, ontimeoutonabort, onload, onloadend, onloadstart, onprogress, ontimeout
Сенсорные технологииTouch TouchEventArgs ontouchstart, ontouchend, ontouchmove, ontouchenter, ontouchleave, ontouchcancelontouchstart, ontouchend, ontouchmove, ontouchenter, ontouchleave, ontouchcancel

TouchPoint представляет одну точку касания на устройстве с сенсорным вводом.TouchPoint represents a single contact point on a touch-sensitive device.

Дополнительные сведения см. в следующих ресурсах:For more information, see the following resources:

Лямбда-выраженияLambda expressions

Также можно использовать лямбда-выражения:Lambda expressions can also be used:

<button @onclick="@(e => Console.WriteLine("Hello, world!"))">Say hello</button>

Часто бывает удобно закрывать дополнительные значения, например при переборе набора элементов.It's often convenient to close over additional values, such as when iterating over a set of elements. В следующем примере создаются три кнопки, каждая из которых вызывает UpdateHeading для передачи аргумента события (MouseEventArgs) и номера кнопки (buttonNumber) при выборе в пользовательском интерфейсе:The following example creates three buttons, each of which calls UpdateHeading passing an event argument (MouseEventArgs) and its button number (buttonNumber) when selected in the UI:

<h2>@message</h2>

@for (var i = 1; i < 4; i++)
{
    var buttonNumber = i;

    <button class="btn btn-primary"
            @onclick="@(e => UpdateHeading(e, buttonNumber))">
        Button #@i
    </button>
}

@code {
    private string message = "Select a button to learn its position.";

    private void UpdateHeading(MouseEventArgs e, int buttonNumber)
    {
        message = $"You selected Button #{buttonNumber} at " +
            $"mouse position: {e.ClientX} X {e.ClientY}.";
    }
}

Примечание

Не используйте переменную цикла непосредственно в лямбда-выражении, например i в предыдущем примере цикла for.Do not use a loop variable directly in a lambda expression, such as i in the preceding for loop example. В противном случае одна и та же переменная будет использоваться во всех лямбда-выражениях, в результате чего значение будет одинаковым во всех лямбда-выражениях.Otherwise, the same variable is used by all lambda expressions, which results in use of the same value in all lambdas. Всегда записывайте значение переменной в локальную переменную, а затем используйте ее.Always capture the variable's value in a local variable and then use it. В предыдущем примере переменная цикла i назначается buttonNumber.In the preceding example, the loop variable i is assigned to buttonNumber.

EventCallbackEventCallback

Распространенным сценарием с вложенными компонентами является запуск метода родительского компонента при возникновении события дочернего компонента,A common scenario with nested components is the desire to run a parent component's method when a child component event occurs. например, когда в дочернем элементе возникает событие onclick.An onclick event occurring in the child component is a common use case. Чтобы обеспечить доступ к событиям в компонентах, используйте EventCallback.To expose events across components, use an EventCallback. Родительский компонент может назначить метод обратного вызова EventCallback дочернего компонента.A parent component can assign a callback method to a child component's EventCallback.

В ChildComponent в примере приложения (Components/ChildComponent.razor) показано, как обработчик onclick кнопки настроен на получение делегата EventCallback из ParentComponent образца.The ChildComponent in the sample app (Components/ChildComponent.razor) demonstrates how a button's onclick handler is set up to receive an EventCallback delegate from the sample's ParentComponent. EventCallback вводится с MouseEventArgs, что подходит для события onclick от периферийного устройства:The EventCallback is typed with MouseEventArgs, which is appropriate for an onclick event from a peripheral device:

<div class="panel panel-default">
    <div class="panel-heading">@Title</div>
    <div class="panel-body">@ChildContent</div>

    <button class="btn btn-primary" @onclick="OnClickCallback">
        Trigger a Parent component method
    </button>
</div>

@code {
    [Parameter]
    public string Title { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter]
    public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}

ParentComponent задает для EventCallback<TValue> дочернего компонента (OnClickCallback) его метод ShowMessage.The ParentComponent sets the child's EventCallback<TValue> (OnClickCallback) to its ShowMessage method.

Pages/ParentComponent.razor:Pages/ParentComponent.razor:

@page "/ParentComponent"

<h1>Parent-child example</h1>

<ChildComponent Title="Panel Title from Parent"
                OnClickCallback="@ShowMessage">
    Content of the child component is supplied
    by the parent component.
</ChildComponent>

<p><b>@messageText</b></p>

@code {
    private string messageText;

    private void ShowMessage(MouseEventArgs e)
    {
        messageText = $"Blaze a new trail with Blazor! ({e.ScreenX}, {e.ScreenY})";
    }
}

При выборе кнопки в ChildComponent:When the button is selected in the ChildComponent:

  • Вызывается метод ShowMessage ParentComponent.The ParentComponent's ShowMessage method is called. messageText обновляется и отображается в ParentComponent.messageText is updated and displayed in the ParentComponent.
  • Вызов StateHasChanged не требуется в методе обратного вызова (ShowMessage).A call to StateHasChanged isn't required in the callback's method (ShowMessage). StateHasChanged вызывается автоматически для повторной отрисовки ParentComponent, так же как и дочерние события запускают повторную отрисовку компонента в обработчиках событий, которые выполняются в дочернем элементе.StateHasChanged is called automatically to rerender the ParentComponent, just as child events trigger component rerendering in event handlers that execute within the child.

EventCallback и EventCallback<TValue> разрешают выполнять асинхронные делегаты.EventCallback and EventCallback<TValue> permit asynchronous delegates. Структура EventCallback слабо типизирована и позволяет передавать любой аргумент типа в InvokeAsync(Object).EventCallback is weakly typed and allows passing any type argument in InvokeAsync(Object). Структура EventCallback<TValue> сильно типизирована и требует передачи аргумента T в InvokeAsync(T), который можно назначить TValue.EventCallback<TValue> is strongly typed and requires passing a T argument in InvokeAsync(T) that's assignable to TValue.

<ChildComponent 
    OnClickCallback="@(async () => { await Task.Yield(); messageText = "Blaze It!"; })" />

Вызов EventCallback или EventCallback<TValue> с InvokeAsync и ожидание Task:Invoke an EventCallback or EventCallback<TValue> with InvokeAsync and await the Task:

await OnClickCallback.InvokeAsync(arg);

Используйте EventCallback и EventCallback<TValue> для обработки событий и параметров компонента привязки.Use EventCallback and EventCallback<TValue> for event handling and binding component parameters.

Предпочтительнее использовать строго типизированный EventCallback<TValue> вместо EventCallback.Prefer the strongly typed EventCallback<TValue> over EventCallback. EventCallback<TValue> обеспечивает более эффективное реагирование на ошибки для пользователей компонента.EventCallback<TValue> provides better error feedback to users of the component. Как и в случае с другими обработчиками событий пользовательского интерфейса, указание параметра события является необязательным.Similar to other UI event handlers, specifying the event parameter is optional. Используйте EventCallback, если в обратный вызов не было передано значение.Use EventCallback when there's no value passed to the callback.

Запрет действий по умолчаниюPrevent default actions

Используйте атрибут директивы @on{EVENT}:preventDefault, чтобы запретить выполнение действия по умолчанию для события.Use the @on{EVENT}:preventDefault directive attribute to prevent the default action for an event.

Если на устройстве ввода выбран ключ, а фокус находится на текстовом поле, то в браузере в текстовом поле обычно отображается символ ключа.When a key is selected on an input device and the element focus is on a text box, a browser normally displays the key's character in the text box. В следующем примере поведение по умолчанию запрещено путем указания атрибута директивы @onkeypress:preventDefault.In the following example, the default behavior is prevented by specifying the @onkeypress:preventDefault directive attribute. Счетчик увеличивается, а ключ + не записывается в значение элемента <input>:The counter increments, and the + key isn't captured into the <input> element's value:

<input value="@count" @onkeypress="KeyHandler" @onkeypress:preventDefault />

@code {
    private int count = 0;

    private void KeyHandler(KeyboardEventArgs e)
    {
        if (e.Key == "+")
        {
            count++;
        }
    }
}

Указание атрибута @on{EVENT}:preventDefault без значения эквивалентно @on{EVENT}:preventDefault="true".Specifying the @on{EVENT}:preventDefault attribute without a value is equivalent to @on{EVENT}:preventDefault="true".

Значение атрибута также может быть выражением.The value of the attribute can also be an expression. В следующем примере shouldPreventDefault является полем bool, для которого задано значение true или false:In the following example, shouldPreventDefault is a bool field set to either true or false:

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

Остановка распространения событийStop event propagation

Используйте атрибут директивы @on{EVENT}:stopPropagation, чтобы остановить распространение событий.Use the @on{EVENT}:stopPropagation directive attribute to stop event propagation.

В следующем примере при установке флажка события щелчка мышью из второго дочернего элемента <div> перестают распространяться в родительский элемент <div>:In the following example, selecting the check box prevents click events from the second child <div> from propagating to the parent <div>:

<label>
    <input @bind="stopPropagation" type="checkbox" />
    Stop Propagation
</label>

<div @onclick="OnSelectParentDiv">
    <h3>Parent div</h3>

    <div @onclick="OnSelectChildDiv">
        Child div that doesn't stop propagation when selected.
    </div>

    <div @onclick="OnSelectChildDiv" @onclick:stopPropagation="stopPropagation">
        Child div that stops propagation when selected.
    </div>
</div>

@code {
    private bool stopPropagation = false;

    private void OnSelectParentDiv() => 
        Console.WriteLine($"The parent div was selected. {DateTime.Now}");
    private void OnSelectChildDiv() => 
        Console.WriteLine($"A child div was selected. {DateTime.Now}");
}

Установка фокуса на элементFocus an element

Вызовите FocusAsync на ссылке на элемент, чтобы установить фокус на элементе в коде:Call FocusAsync on an element reference to focus an element in code:

<input @ref="exampleInput" />

<button @onclick="ChangeFocus">Focus the Input Element</button>

@code {
    private ElementReference exampleInput;

    private async Task ChangeFocus()
    {
        await exampleInput.FocusAsync();
    }
}