--- title: ASP.NET Core Blazor event handling author: guardrex description: Learn about Blazor's event handling features, including event argument types, event callbacks, and managing default browser events. monikerRange: '>= aspnetcore-3.1' ms.author: riande ms.custom: mvc ms.date: 03/16/2020 no-loc: [Blazor, SignalR] uid: blazor/event-handling --- # ASP.NET Core Blazor event handling By [Luke Latham](https://github.com/guardrex) and [Daniel Roth](https://github.com/danroth27) Razor components provide event handling features. For an HTML element attribute named [`@on{EVENT}`](xref:mvc/views/razor#onevent) (for example, `@onclick`) with a delegate-typed value, a Razor component treats the attribute's value as an event handler. The following code calls the `UpdateHeading` method when the button is selected in the UI: ```razor @code { private void UpdateHeading(MouseEventArgs e) { ... } } ``` The following code calls the `CheckChanged` method when the check box is changed in the UI: ```razor @code { private void CheckChanged() { ... } } ``` Event handlers can also be asynchronous and return a . There's no need to manually call [StateHasChanged](xref:blazor/lifecycle#state-changes). Exceptions are logged when they occur. In the following example, `UpdateHeading` is called asynchronously when the button is selected: ```razor @code { private async Task UpdateHeading(MouseEventArgs e) { ... } } ``` ## Event argument types For some events, event argument types are permitted. Specifying an event type in the method call is only necessary if the event type is used in the method. Supported `EventArgs` are shown in the following table. | Event | Class | DOM events and notes | | ---------------- | -------------------- | -------------------- | | Clipboard | `ClipboardEventArgs` | `oncut`, `oncopy`, `onpaste` | | Drag | `DragEventArgs` | `ondrag`, `ondragstart`, `ondragenter`, `ondragleave`, `ondragover`, `ondrop`, `ondragend`

`DataTransfer` and `DataTransferItem` hold dragged item data. | | Error | `ErrorEventArgs` | `onerror` | | Event | `EventArgs` | *General*
`onactivate`, `onbeforeactivate`, `onbeforedeactivate`, `ondeactivate`, `onended`, `onfullscreenchange`, `onfullscreenerror`, `onloadeddata`, `onloadedmetadata`, `onpointerlockchange`, `onpointerlockerror`, `onreadystatechange`, `onscroll`

*Clipboard*
`onbeforecut`, `onbeforecopy`, `onbeforepaste`

*Input*
`oninvalid`, `onreset`, `onselect`, `onselectionchange`, `onselectstart`, `onsubmit`

*Media*
`oncanplay`, `oncanplaythrough`, `oncuechange`, `ondurationchange`, `onemptied`, `onpause`, `onplay`, `onplaying`, `onratechange`, `onseeked`, `onseeking`, `onstalled`, `onstop`, `onsuspend`, `ontimeupdate`, `onvolumechange`, `onwaiting` | | Focus | `FocusEventArgs` | `onfocus`, `onblur`, `onfocusin`, `onfocusout`

Doesn't include support for `relatedTarget`. | | Input | `ChangeEventArgs` | `onchange`, `oninput` | | Keyboard | `KeyboardEventArgs` | `onkeydown`, `onkeypress`, `onkeyup` | | Mouse | `MouseEventArgs` | `onclick`, `oncontextmenu`, `ondblclick`, `onmousedown`, `onmouseup`, `onmouseover`, `onmousemove`, `onmouseout` | | Mouse pointer | `PointerEventArgs` | `onpointerdown`, `onpointerup`, `onpointercancel`, `onpointermove`, `onpointerover`, `onpointerout`, `onpointerenter`, `onpointerleave`, `ongotpointercapture`, `onlostpointercapture` | | Mouse wheel | `WheelEventArgs` | `onwheel`, `onmousewheel` | | Progress | `ProgressEventArgs` | `onabort`, `onload`, `onloadend`, `onloadstart`, `onprogress`, `ontimeout` | | Touch | `TouchEventArgs` | `ontouchstart`, `ontouchend`, `ontouchmove`, `ontouchenter`, `ontouchleave`, `ontouchcancel`

`TouchPoint` represents a single contact point on a touch-sensitive device. | For more information, see the following resources: * [EventArgs classes in the ASP.NET Core reference source (dotnet/aspnetcore release/3.1 branch)](https://github.com/dotnet/aspnetcore/tree/release/3.1/src/Components/Web/src/Web). * [MDN web docs: GlobalEventHandlers](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers) – Includes information on which HTML elements support each DOM event. ## Lambda expressions [Lambda expressions](/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions) can also be used: ```razor ``` It's often convenient to close over additional values, such as when iterating over a set of elements. 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: ```razor

@_message

@for (var i = 1; i < 4; i++) { var buttonNumber = i; } @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}."; } } ``` > [!NOTE] > Do **not** use the loop variable (`i`) in a `for` loop directly in a lambda expression. Otherwise the same variable is used by all lambda expressions causing `i`'s value to be the same in all lambdas. Always capture its value in a local variable (`buttonNumber` in the preceding example) and then use it. ## EventCallback A common scenario with nested components is the desire to run a parent component's method when a child component event occurs—for example, when an `onclick` event occurs in the child. To expose events across components, use an `EventCallback`. A parent component can assign a callback method to a child component's `EventCallback`. 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`. The `EventCallback` is typed with `MouseEventArgs`, which is appropriate for an `onclick` event from a peripheral device: [!code-razor[](common/samples/3.x/BlazorWebAssemblySample/Components/ChildComponent.razor?highlight=5-7,17-18)] The `ParentComponent` sets the child's `EventCallback` (`OnClickCallback`) to its `ShowMessage` method. *Pages/ParentComponent.razor*: ```razor @page "/ParentComponent"

Parent-child example

Content of the child component is supplied by the parent component.

@_messageText

@code { private string _messageText; private void ShowMessage(MouseEventArgs e) { _messageText = $"Blaze a new trail with Blazor! ({e.ScreenX}, {e.ScreenY})"; } } ``` When the button is selected in the `ChildComponent`: * The `ParentComponent`'s `ShowMessage` method is called. `_messageText` is updated and displayed in the `ParentComponent`. * A call to [StateHasChanged](xref:blazor/lifecycle#state-changes) isn't required in the callback's method (`ShowMessage`). `StateHasChanged` is called automatically to rerender the `ParentComponent`, just as child events trigger component rerendering in event handlers that execute within the child. `EventCallback` and `EventCallback` permit asynchronous delegates. `EventCallback` is strongly typed and requires a specific argument type. `EventCallback` is weakly typed and allows any argument type. ```razor ``` Invoke an `EventCallback` or `EventCallback` with `InvokeAsync` and await the : ```csharp await callback.InvokeAsync(arg); ``` Use `EventCallback` and `EventCallback` for event handling and binding component parameters. Prefer the strongly typed `EventCallback` over `EventCallback`. `EventCallback` provides better error feedback to users of the component. Similar to other UI event handlers, specifying the event parameter is optional. Use `EventCallback` when there's no value passed to the callback. ## Prevent default actions Use the [`@on{EVENT}:preventDefault`](xref:mvc/views/razor#oneventpreventdefault) 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. In the following example, the default behavior is prevented by specifying the `@onkeypress:preventDefault` directive attribute. The counter increments, and the **+** key isn't captured into the `` element's value: ```razor @code { private int _count = 0; private void KeyHandler(KeyboardEventArgs e) { if (e.Key == "+") { _count++; } } } ``` 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. In the following example, `_shouldPreventDefault` is a `bool` field set to either `true` or `false`: ```razor ``` An event handler isn't required to prevent the default action. The event handler and prevent default action scenarios can be used independently. ## Stop event propagation Use the [`@on{EVENT}:stopPropagation`](xref:mvc/views/razor#oneventstoppropagation) directive attribute to stop event propagation. In the following example, selecting the check box prevents click events from the second child `
` from propagating to the parent `
`: ```razor

Parent div

Child div that doesn't stop propagation when selected.
Child div that stops propagation when selected.
@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}"); } ```