--- 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: 09/17/2020 no-loc: ["ASP.NET Core Identity", cookie, Cookie, Blazor, "Blazor Server", "Blazor WebAssembly", "Identity", "Let's Encrypt", Razor, SignalR] uid: blazor/components/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/components/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 parameter in an event method definition is optional and only necessary if the event type is used in the method. In the following example, the `MouseEventArgs` event argument is used in the `ShowMessage` method to set message text: ```csharp private void ShowMessage(MouseEventArgs e) { messageText = $"The mouse is at coordinates: {e.ScreenX}:{e.ScreenY}"; } ``` Supported are shown in the following table. ::: moniker range=">= aspnetcore-5.0" | Event | Class | DOM events and notes | | ---------------- | ------ | -------------------- | | Clipboard | | `oncut`, `oncopy`, `onpaste` | | Drag | | `ondrag`, `ondragstart`, `ondragenter`, `ondragleave`, `ondragover`, `ondrop`, `ondragend`

and hold dragged item data.

Implement drag and drop in Blazor apps using [JS interop](xref:blazor/call-javascript-from-dotnet) with [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). | | Error | | `onerror` | | Event | | *General*
`onactivate`, `onbeforeactivate`, `onbeforedeactivate`, `ondeactivate`, `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`, `onended`, `onpause`, `onplay`, `onplaying`, `onratechange`, `onseeked`, `onseeking`, `onstalled`, `onstop`, `onsuspend`, `ontimeupdate`, `ontoggle`, `onvolumechange`, `onwaiting`

holds attributes to configure the mappings between event names and event argument types. | | Focus | | `onfocus`, `onblur`, `onfocusin`, `onfocusout`

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

represents a single contact point on a touch-sensitive device. | ::: moniker-end ::: moniker range="< aspnetcore-5.0" | Event | Class | DOM events and notes | | ---------------- | ----- | -------------------- | | Clipboard | | `oncut`, `oncopy`, `onpaste` | | Drag | | `ondrag`, `ondragstart`, `ondragenter`, `ondragleave`, `ondragover`, `ondrop`, `ondragend`

and hold dragged item data.

Implement drag and drop in Blazor apps using [JS interop](xref:blazor/call-javascript-from-dotnet) with [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). | | Error | | `onerror` | | Event | | *General*
`onactivate`, `onbeforeactivate`, `onbeforedeactivate`, `ondeactivate`, `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`, `onended`, `onpause`, `onplay`, `onplaying`, `onratechange`, `onseeked`, `onseeking`, `onstalled`, `onstop`, `onsuspend`, `ontimeupdate`, `onvolumechange`, `onwaiting`

holds attributes to configure the mappings between event names and event argument types. | | Focus | | `onfocus`, `onblur`, `onfocusin`, `onfocusout`

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

represents a single contact point on a touch-sensitive device. | ::: moniker-end For more information, see the following resources: * [`EventArgs` classes in the ASP.NET Core reference source (dotnet/aspnetcore `master` branch)](https://github.com/dotnet/aspnetcore/tree/master/src/Components/Web/src/Web). The `master` branch represents API under development for the *next* ASP.NET Core release. For the current release, select the appropriate GitHub repository branch (for example, `release/3.1`). * [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 () 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 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. In the preceding example, the loop variable `i` is assigned to `buttonNumber`. ## EventCallback A common scenario with nested components is the desire to run a parent component's method when a child component event occurs. An `onclick` event occurring in the child component is a common use case. To expose events across components, use an . A parent component can assign a callback method to a child component's . The `ChildComponent` in the sample app (`Components/ChildComponent.razor`) demonstrates how a button's `onclick` handler is set up to receive an delegate from the sample's `ParentComponent`. The 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 (`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/components/lifecycle#state-changes) isn't required in the callback's method (`ShowMessage`). is called automatically to rerender the `ParentComponent`, just as child events trigger component rerendering in event handlers that execute within the child. and permit asynchronous delegates. is weakly typed and allows passing any type argument in `InvokeAsync(Object)`. is strongly typed and requires passing a `T` argument in `InvokeAsync(T)` that's assignable to `TValue`. ```razor ``` Invoke an or with and await the : ```csharp await OnClickCallback.InvokeAsync(arg); ``` Use and for event handling and binding component parameters. Prefer the strongly typed over . provides better error feedback to users of the component. Similar to other UI event handlers, specifying the event parameter is optional. Use 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 ``` ## 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}"); } ```