Blazor 事件处理开发指南
翻译自 Waqas Anwar 2021年3月25日的文章 《A Developer’s Guide To Blazor Event Handling》 [1]

如果您正在开发交互式 Web 应用程序,根据不同的应用程序事件和用户操作动态更新用户界面是十分常见的做法。这些操作会触发事件,而作为开发人员,我们的工作是使用一些事件处理技术来处理这些事件。Blazor 内置支持处理多种事件,比如 onclick、onchange 和 onmousemove 等,并为开发者提供了处理这些事件的多种方式。我将在本教程中概述 Blazor 事件处理。此外,我还将介绍如何在 Blazor 中使用事件参数和 Lambda 表达式,以及如何将附加参数传递给事件处理程序。
Blazor 事件处理入门
Blazor 中处理事件的基本语法如下所示:
@on[DOM EVENT]="[DELEGATE]"
在上面的语法中
- [DOM EVENT] 是 DOM 事件的占位符,例如 click、mouseup 等。
- [DELEGATE] 是 C# 委托事件处理程序的占位符。
假设您要处理按钮单击事件,您可以按如下方式使用上述语法:
<button @onclick="Update" />
让我们通过一些实际的例子来更详细地介绍一下事件处理。 在 Visual Studio 2019 中创建一个新的 Blazor Server 应用程序,然后添加一个新的 Blazor 组件 Calculator.razor。
@page "/calculator"
<h3>Calculator</h3>
<div class="form-group">
<label for="number1">Number 1</label>
<input type="number" class="form-control" id="number1" @bind="number1">
</div>
<div class="form-group">
<label for="number2">Number 2</label>
<input type="number" class="form-control" id="number2" @bind="number2">
</div>
<div class="form-group">
<label><b>Total: </b>@total</label>
</div>
<button class="btn btn-primary" @onclick="Calculate">Calculate</button>
<button class="btn btn-secondary" @onclick="Clear">Clear</button>
@code {
private int number1 = 0;
private int number2 = 0;
private int total = 0;
private void Calculate()
{
total = number1 + number2;
}
private void Clear()
{
number1 = 0;
number2 = 0;
total = 0;
}
}
上面的组件中有两个按钮:Calculate 和 Clear,它们都处理了 onclick 事件,并调用了上面的 @code 代码块中编写的 Calculate 和 Clear 方法。
<button class="btn btn-primary" @onclick="Calculate">Calculate</button>
<button class="btn btn-secondary" @onclick="Clear">Clear</button>
如果您运行这个简单的示例,将看到类似于以下内容的页面。在文本框中输入一些数字,然后按下按钮查看事件处理的效果。

如下面的代码片段所示,Blazor 还支持异步委托事件处理程序。这些处理程序类型会返回一个 Task,在其内部我们可以使用 await 关键字调用异步方法。
private async Task Clear()
{
await Task.Delay(10);
number1 = 0;
number2 = 0;
total = 0;
}
理解 Blazor 事件参数
大部分 Blazor 事件支持事件参数,这些参数是携带触发事件的相关信息的对象。例如,KeyboardEventArgs 可以为我们提供用户按下的按键的详细信息。
让我们创建一个带有标准的 HTML div 元素的基本组件,如下所示。
@page "/mouseevents"
<h3>Mouse Events</h3>
<div style="width: 400px; height: 400px; background: lightblue" @onmousemove="Move"></div>
<label><b>Coordinates: </b>@coordinates</label>
@code {
private string coordinates = "";
private void Move(MouseEventArgs e)
{
coordinates = $"{e.ScreenX}:{e.ScreenY}";
}
}
上面的 div 元素处理 onmousemove 事件并将 MouseEventArgs 传递给方法名为 Move 的事件处理程序。然后,Move 事件处理程序使用 MouseEventArgs 类中提供的 ScreenX 和 ScreenY 属性,用鼠标的 X 和 Y 位置更新本地字段 coordinates。运行应用程序,并尝试在 div 中移动鼠标,您将看到坐标会实时更新。

Blazor 支持大量的 EventArgs 对象,但最常用的 EventArgs 如下表所示:
| 事件 | 类 | DOM 事件 |
|---|---|---|
| 焦点(Focus) | FocusEventArgs | onfocus, onblur, onfocusin, onfocusout |
| 输入(Input) | ChangeEventArgs | onchange, oninput |
| 键盘(Keyboard) | KeyboardEventArgs | onkeydown, onkeypress, onkeyup |
| 鼠标(Mouse) | MouseEventArgs | onclick, oncontextmenu, ondblclick, onmousedown, onmouseup, onmouseover, onmousemove, onmouseout |
| 鼠标滚轮(Mouse wheel) | WheelEventArgs | onwheel, onmousewheel |
| 触控(Touch) | TouchEventArgs | ontouchstart, ontouchend, ontouchmove, ontouchenter, ontouchleave, ontouchcancel |
您可以在微软 Blazor 文档页面[2]上看到 EventArgs 的完整列表。
在 Blazor 事件中使用 Lambda 表达式
Blazor 还支持将 Lambda 表达式作为委托事件处理程序。您应当只在简单的用例中使用这些表达式,如果有很多的代码要执行,应避免使用 Lambda 表达式。让我们修改一下前面的 Calculator 示例,这次使用 Lambda 表达式替代上面的 Calculate 和 Clear 方法。
@page "/calculator"
<h3>Calculator</h3>
<div class="form-group">
<label for="number1">Number 1</label>
<input type="number" class="form-control" id="number1" @bind="number1">
</div>
<div class="form-group">
<label for="number2">Number 2</label>
<input type="number" class="form-control" id="number2" @bind="number2">
</div>
<div class="form-group">
<label><b>Total: </b>@total</label>
</div>
<button class="btn btn-primary" @onclick="@(e => total = number1 + number2)">Calculate</button>
<button class="btn btn-secondary" @onclick="@(e => total = number1 = number2 = 0)">Clear</button>
@code {
private int number1 = 0;
private int number2 = 0;
private int total = 0;
}
向事件处理程序传递附加参数
有时,我们希望根据每个应用程序的需要向事件处理程序传递额外的参数。例如,在一个循环中,您可能希望将循环迭代索引号传递给事件参数,以便您知道此事件处理程序是针对循环中的哪一项执行的。另一个简单的例子是,从两个或多个控件调用相同的事件处理程序,并传递控件的引用以处理事件。让我们用一个基础的例子来介绍一下这个概念。依照下面的代码片段再次修改 Calculator 的代码。
<div class="form-group">
<label for="number1">Number 1</label>
<input type="number" class="form-control" id="number1" @bind="number1">
</div>
<div class="form-group">
<label for="number2">Number 2</label>
<input type="number" class="form-control" id="number2" @bind="number2">
</div>
<div class="form-group">
<label><b>Total: </b>@total</label>
</div>
<button class="btn btn-primary" @onclick="@(e => Calculate(e, 1))">Add</button>
<button class="btn btn-primary" @onclick="@(e => Calculate(e, 2))">Subtract</button>
<button class="btn btn-secondary" @onclick="Clear">Clear</button>
@code {
private int number1 = 0;
private int number2 = 0;
private int total = 0;
private void Calculate(MouseEventArgs e, int buttonType)
{
switch (buttonType)
{
case 1:
total = number1 + number2;
break;
case 2:
total = number1 - number2;
break;
}
}
private void Clear()
{
number1 = 0;
number2 = 0;
total = 0;
}
}
在上面代码片段中,重要的两行如下,我将一个附加参数传递给了 Calculate 方法,其值分别为 1 和 2:
<button class="btn btn-primary" @onclick="@(e => Calculate(e, 1))">Add</button>
<button class="btn btn-primary" @onclick="@(e => Calculate(e, 2))">Subtract</button>
方法 Calculate 的代码也略有修改,因为现在它接受一个额外的参数 buttonType。在此方法中,我们根据 buttonType 参数的值进行加法或减法运算。
private void Calculate(MouseEventArgs e, int buttonType)
{
switch (buttonType)
{
case 1:
total = number1 + number2;
break
case 2:
total = number1 - number2;
break;
}
}
再次运行应用程序,并尝试点击 Add 和 Subtract 方法,您会看到相同的 Calculate 方法给了我们不同的结果。

相关阅读:
https://www.ezzylearning.net/tutorial/a-developers-guide-to-blazor-event-handling A Developer’s Guide To Blazor Event Handling ︎
https://docs.microsoft.com/zh-cn/aspnet/core/blazor/components/event-handling ASP.NET Core Blazor 事件处理 ︎
Blazor 事件处理开发指南的更多相关文章
- Blazor 数据绑定开发指南
翻译自 Waqas Anwar 2021年3月21日的文章 <A Developer's Guide to Blazor Data Binding> [1] 现如今,大多数 Web 应用程 ...
- Blazor 路由及导航开发指南
翻译自 Waqas Anwar 2021年4月2日的文章 <A Developer's Guide To Blazor Routing and Navigation> [1] 检查传入的请 ...
- Blazor 模板化组件开发指南
翻译自 Waqas Anwar 2021年4月15日的文章 <A Developer's Guide To Blazor Templated Components> [1] 在我之前的一篇 ...
- Blazor 组件库开发指南
翻译自 Waqas Anwar 2021年5月21日的文章 <A Developer's Guide To Blazor Component Libraries> [1] Blazor 的 ...
- 关于《Swift开发指南》背后的那些事
时间轴(倒叙)2014年8月底在图灵出版社的大力支持下,全球第一本全面.系统.科学的,包含本人多年经验的呕心沥血之作<Swift开发指南>(配有同步视频课程和同步练习)全线重磅推出2014 ...
- 视频聊天插件:AnyChat使用攻略之iOS开发指南
AnyChat使用攻略之iOS开发指南 这套攻略主要指导刚开始使用AnyChat SDK For iOS的同学,快速搭建SDK环境,和实现音视频开发流程. (需要工程案例文件可联系我们) 在iOS平台 ...
- Delphi for iOS开发指南(7):在iOS应用程序中使用WebBrowser组件
Delphi for iOS开发指南(7):在iOS应用程序中使用WebBrowser组件 在FireMonkey iOS应用程序中使用WebBrowser 在iOS平台上,FireMonkey使用T ...
- Delphi for iOS开发指南(6):在iOS应用程序中使用ComboBox组件来从列表中选择某一项
http://blog.csdn.net/delphiteacher/article/details/8924110 Delphi for iOS开发指南(6):在iOS应用程序中使用ComboBox ...
- Delphi for iOS开发指南(3):创建一个FireMonkey iOS应用程序
http://cache.baiducontent.com/c?m=9d78d513d9d431a94f9d92697d60c015134381132ba1d0020fa48449e3732b4b50 ...
随机推荐
- redis 记一次搭建高可用redis集群过程,问题解决;Node 192.168.184.133:8001 is not configured as a cluster node
------------恢复内容开始------------ 步骤 1:每台redis服务器启动之后,需要将这几台redis关联起来, 2: 关联命令启动之后 报错: Node 192.168.184 ...
- 计算机网络-ip分类
本网络--网络号全是0(0000 0000)的IP地址是保留地址,意思是"本网络". 环回地址--网络号是127(0111 1111)的IP地址也是保留地址,作为本地环回软件测试. ...
- Linux学习笔记:Linux命令之权限管理命令
权限管理命令 chmod(重要) 命令名称:chmod 英文原意:change the permissions mode of a file 执行权限:所有用户 功能描述:改变文件或目录权限 语法:c ...
- 【linux】驱动-14-异步通知
目录 前言 14. 异步通知 14.1 异步通知的一些概念 14.2 Linux 信号 14.3 信号接收 14.4 使用流程 14.4.1 参考流程图 14.4.2 分析&编程步骤 14.4 ...
- Java8-四个函数式接口(Consumer,Supplier,Predicate,Function)
Java8---函数式接口 Consumer---消费者(accept方法,Lambda与方法引用返回都是Consumer) Supplier---供给型(get方法,返回数据,与Optional可以 ...
- 解决mac中adb: command not found
在Mac系统中,很多时候第一次在Android SDK中使用adb的时候.无法使用.会提示-bash: abd: command not found. 造成此类现象的原因是:未配置Android的环境 ...
- Kubernetes ConfigMap详解,多种方式创建、多种方式使用
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 配置是程序绕不开的话题,在Kubernetes中使用ConfigMap来配置,它本质其实就是键值对.本文讲解如何 ...
- 在vue中下拉框切换事件中改新建表单中的一个值,页面不显示
事件中改新建表单中的一个值,页面不显示,当另一个对象值发生改变时,这个页面上的值才会显示 由于新建表单是弹窗,在弹出时会重新给每个字段重新赋值,在赋值时没给这个字段赋值(常见新加功能时,加了一个字段, ...
- DNS 解析过程
DNS 是应用层协议,用于将域名转换成 IP 地址. 1. 解析过程 DNS 的核心系统是一个三层的树状.分布式服务,基本对应域名的结构. 根域名服务器:管理顶级域名服务器,返回 com.net.cn ...
- ceph-csi源码分析(4)-rbd driver-controllerserver分析
更多ceph-csi其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 ceph-csi源码分析(4)-rbd driver-controllerserver分析 当 ...