如何在不使用 Blazor 中的输入标签的情况下检测按键

How to detect key press without using an input tag in Blazor

我希望能够在不使用 Blazor 中的 HTML INPUT 标记的情况下捕获键盘输入。按下键后,我将显示一个图形来表示按下的字母。

像这样

@page "/counter"
@using Microsoft.AspNetCore.Components.Web

<div @onkeypress="e => KeyPress(e)">
    Press any letter key
</div>

@code {

    private void KeyPress(KeyboardEventArgs e)
    {
        var letter = e.Key;
    }
}

当我在其上设置断点时,KeyPress 方法似乎没有被调用。非常感谢任何帮助。

你快到了,但是你忘了让 div 集中注意力。这是步骤:

0.- 添加 tabindex 标签使您的 div 可聚焦:

<div 
    class="jumbotron"
    @onkeydown="@KeyDown"
    tabindex="0"
    @ref="myDiv" >
   <h1 class="display-4">
       @letter
   </h1>   
</div>

1.- 创建一个 js 代码以将焦点设置到您的 div,例如 _Host.cshtml

    <script>
        window.SetFocusToElement = (element) => {
            element.focus();
        };
    </script>

此函数将元素引用作为参数。

2.- 在您的组件呈现后调用此函数。


protected ElementReference myDiv;  // set by the @ref attribute

protected async override Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender) 
    {
        await JSRuntime.InvokeVoidAsync("SetFocusToElement", myDiv);
    }            
}  

3.- 实现你自己的 KeyDown:

protected void KeyDown(KeyboardEventArgs e)
{
    letter = $"Pressed: [{e.Key}]";
}

请注意,这不是 Blazor 问题,只是默认的 html 和 js 行为。我在编写游戏时学会了它,请在 Blagario 实验室查看。

运行:

演示在 Flappy Blazor Bird

2019 年 11 月编辑:

代码改进 @Quango(非常感谢)

如果还有人要解决方案。我认为现在在 .NET 5 中,您可以在没有 js 的情况下在 Blazor 中实现这一点。设置焦点和 tabindex 很重要,当您失去焦点或将焦点设置到另一个元素时,这将不起作用。这对我有用:

    <table @ref="testRef" tabindex="0" @onkeydown="HandleKeyDown">
    <thead>
        <tr>
            <th>
                Pressed Key
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                @pressedKey
            </td>
        </tr>
    </tbody>
    </table>

    private ElementReference testRef;
    private string pressedKey;
    
    private void HandleKeyDown(KeyboardEventArgs e)
    {
        pressedKey = e.Key;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await testRef.FocusAsync();
        }
    }