MAUI中如何获取移动虚拟键盘的按键输入?
MAUI中如何获取移动虚拟键盘的按键输入?
我太懂你这种摸不着头脑的感觉了!原生HTML的onkeyup="this.value = this.value.toUpperCase()"明明在移动端每按一个键都能触发,换成Blazor的@onkeyup却只认回车,还拿不到完整的按键信息,确实让人百思不得其解😩
问题根源
其实这是Blazor对移动端虚拟键盘的事件处理局限导致的:虚拟键盘和物理键盘的事件机制差异很大,Blazor封装的KeyboardEventArgs在移动端很多时候无法捕获到完整的按键数据,只有回车这类系统级按键会触发事件,而且Code字段经常是空的。而原生JS的事件是直接绑定到DOM元素上,浏览器对它的兼容逻辑更适配移动端虚拟键盘。
解决方案:原生JS + Blazor互操作
既然原生JS能正常工作,我们可以借助Blazor的JS互操作,把原生的按键事件传递给Blazor处理,步骤如下:
- 添加原生JS监听函数
在你的MAUI Blazor项目的wwwroot/index.html(或独立JS文件)里添加这段代码:
// 注册按键监听 window.setupKeyListener = function (elementId, dotNetRef) { const inputElement = document.getElementById(elementId); inputElement.addEventListener('keyup', (e) => { // 将按键信息传给Blazor方法 dotNetRef.invokeMethodAsync('HandleKeyPress', e.key, e.code); }); }; // 移除监听(避免内存泄漏) window.removeKeyListener = function (elementId) { const inputElement = document.getElementById(elementId); inputElement.removeEventListener('keyup'); };
- 在Blazor组件中绑定并处理事件
修改你的组件代码,通过OnAfterRenderAsync注册监听,并实现对应的处理方法:
<input @bind="StringInput" id="textInput" />
@inject IJSRuntime JS @implements IDisposable @code { private string StringInput = string.Empty; private DotNetObjectReference<YourComponentName>? _dotNetRef; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { _dotNetRef = DotNetObjectReference.Create(this); await JS.InvokeVoidAsync("setupKeyListener", "textInput", _dotNetRef); } } [JSInvokable] public void HandleKeyPress(string key, string code) { // 这里就可以拿到每个按键的信息了! Console.WriteLine($"按下的键: {key}, 按键码: {code}"); // 如果你需要同步处理输入值,比如转大写,也可以在这里操作 StringInput = StringInput.ToUpper(); StateHasChanged(); } public void Dispose() { _dotNetRef?.Dispose(); JS.InvokeVoidAsync("removeKeyListener", "textInput"); } }
补充说明
- 如果你不需要精确的按键码,只是想监听输入值的变化,也可以用Blazor的
@oninput事件,它在移动端虚拟键盘输入时能正常触发,不过它拿不到具体的按键信息,只能拿到变化后的值。 - 测试的时候要注意在真实的移动设备或靠谱的模拟器上验证,有些桌面浏览器的移动端模拟可能和真实设备有差异。
备注:内容来源于stack exchange,提问作者Frasher Gray
相关产品推荐
相关产品推荐

