第三章组件(6)-事件处理
- 电脑硬件
- 2025-08-25 07:54:01

事件的常规使用 一、事件处理程序
@on{DOM事件}:为HTML元素的指定事件设置事件处理程序。
Razor组件中,在HTML元素上,可以看到一系列@on{DOM事件}指令,这些都是微软根据Html元素对应的DOM事件进行封装的一种机制,其类型为EventCallback<T>或EventCallback(事件回调,也可以称为事件处理程序)
支持返回Task的事件处理程序允许组件之间进行类型安全的事件传递和回调。注意,EventCallback<T>或EventCallback事件处理程序执行后,会自动刷新 UI,这是 Blazor 的一个核心特性,称为“自动状态管理”。事件处理程序仅在交互模式下会执行。示例1-设置事件处理程序(同步)
@page "/counter" @rendermode InteractiveServer <div> <button @onclick="Test">按钮</button> </div> @count @code{ private int count = 0; private void Test(MouseEventArgs args) //这个args参数,如果不需要,可以不声明 { count += 1; } }示例2-设置事件处理程序(异步)
@page "/event-handler" <PageTitle>Event Handler</PageTitle> <h1>Event Handler Example</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})"; } }示例3-组件之间通过组件参数传递事件处理程序
@* EventTest.razor *@ <h3>EventTest</h3> <div> <button @onclick="Test">按钮</button> </div> @code { [Parameter] public EventCallback<MouseEventArgs> Test { get; set; } } @page "/counter" @rendermode InteractiveServer <EventTest Test="Test"/> @count @code{ private int count = 0; private void Test(MouseEventArgs args) { count += 1; } }内置的事件参数
对于支持事件参数的DOM事件,在指定事件处理程序时,可以在参数列表中声明事件参数来接收。
下面的例子中,ReportPointerLocation方法使用了 MouseEventArgs 来设置消息文本,以便在用户选择 UI 中的按钮时获取鼠标坐标
示例
@page "/event-handler" <PageTitle>Event Handler</PageTitle> <h1>Event Handler Example</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}"; } }非内置事件参数的参数
有时,可能在执行事件处理程序时,希望传入一些自定义的参数,此时可以在设置事件处理程序时,通过Lambda表达式,再做一层处理,然后将参数传入到真正的事件处理方法上。
示例-lambda表达式
@page "/counter" @rendermode InteractiveServer <div> <button @onclick="@((args)=>Test(args,"如果要传入自定义的参数,可以使用一下Lambda"))">按钮</button> </div> @count @message @code{ private int count = 0; private string message = ""; private void Test(MouseEventArgs agrs, string param) { count += 1; message = param; } } 三、自定义事件Blazor 支持自定义事件(这里的自定义事件是在DOM事件的基础上的),在自定义事件中,可以设置自定义的事件参数,借助这些参数,可以将任意数据通过自定义事件传递给 .NET 事件处理程序。
创建JS初始设置项
在 root下添加{ASSEMBLY NAME}.lib.module.js文件
每个事件仅在脚本中调用 registerCustomEventType 一次。
BlazorServer.lib.module.js
export function afterWebStarted(blazor) { blazor.registerCustomEventType('custompaste', { browserEventName: 'paste', createEventArgs: event => { return { eventTimestamp: new Date(), pastedData: event.clipboardData.getData('text') }; } }); }创建C#事件处理类与参数
一般情况下,可以在项目中新建CustomEvents文件夹,在其中创建自定义事件处理类以及自定义事件参数
事件处理类必须使用[EventHandler]特性进行注释,静态的且名为EventHandlers,这样才可以被Razor编译器找到。
CustomPasteEventArgs.cs
[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; } }在组件中使用
CustomPasteArguments.razor
@page "/custom-paste-arguments" @rendermode InteractiveServer @using BlazorServer.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}"; } } 跨组件公开事件在项目开发过程中,很多情况下会遇到希望在子组件中触发某个事件时,能够调用到父组件中的处理方法。这里所说的跨组件公开事件,指的是子组件向父组件公开EventCallback组件参数,父组件在使用子组件时,通过组件参数,给子组件设置对应的事件处理方法。
EventCallback与EventCallback<TValue>: 事件回调(事件处理程序),可以在组件中配合[Parameter]定义组件参数暴露给使用者,接收委托作为事件的实际处理方法。
HasDelegate:获取当前EventCallback<TValue>对象是否具有委托。
InvokeAsync([Object]):调用与此绑定关联的委托,如果需要,可以传入一个object参数给委托。
如果需要给委托传递值,建议优先使用EventCallback<TValue>而不是EventCallback,有利于VS的错误反馈,当然如果不需要传递任何值,直接用EventCallback就可以了 。
EventCallback调用的委托后会自动调用StateHasChanged()方法进行重新渲染,没必要手动调用。
Child.razor
<h3>Child 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!"); } }ParentChild.razor
@page "/parent-child" @rendermode InteractiveServer <PageTitle>Parent Child</PageTitle> <h1>Parent Child Example</h1> <div> <Child OnClickCallback="(value) => { message1 = value; }" /> @message1 </div> <div> <Child OnClickCallback="async (value) => { await Task.Delay(2000); message2 = value; }"/> @message2 </div> @code { private string message1 = string.Empty; private string message2 = string.Empty; } 其他操作 一、阻止默认操作一般情况下,DOM事件都有自己的默认行为。例如,当我们将焦点定位在某个文本框上并按下某个按键时,浏览器通常在该文本框中输入该键的字符。如果我们不希望件字符直接输入到文本框中,可以通过使用Razor属性指令@on{DOM EVENT}:preventDefault来阻止默认行为。
示例
@page "/event-handler" @rendermode InteractiveServer <PageTitle>Event Handler</PageTitle> <h1>Event Handler Example</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++; } } } 二、聚焦元素可以调用元素对象的FocusAsync方法来将元素作为焦点。
示例
<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(); } } 三、停止事件传播使用 @on{DOM EVENT}:stopPropagation 指令属性来停止事件在 Blazor 范围内传播。 {DOM EVENT} 是 DOM 事件的占位符。
stopPropagation 指令属性的效果仅限于 Blazor 范围,不会扩展到 HTML DOM。 事件必须传播到 HTML DOM 根目录,然后 Blazor 才能对其进行操作。
示例
@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}"; }第三章组件(6)-事件处理由讯客互联电脑硬件栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“第三章组件(6)-事件处理”
下一篇
Netty入门详解