--- title: ASP.NET Core Blazor event handling author: guardrex description: Learn about Blazor's event handling scenarios, including event argument types, event callbacks, and managing default browser events. monikerRange: '>= aspnetcore-3.1' ms.author: riande ms.custom: mvc ms.date: 02/12/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}` (for example, `onclick` and `onsubmit`) with a delegate-typed value, Razor components treats the attribute's value as an event handler. The attribute's name is always formatted [`@on{EVENT}`](xref:mvc/views/razor#onevent). 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. If access to one of these event types isn't necessary, it isn't required in the method call. 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}"); } ```