You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET MAUI中检测键盘退格键(Android与iOS实现)

从Xamarin.Forms迁移至.NET MAUI:实现带退格焦点切换的自定义PIN输入框

.NET MAUI不再使用Xamarin.Forms中的自定义渲染器(Custom Renderer),而是采用Handlers实现平台特定逻辑。以下是针对4位PIN输入场景,从Xamarin迁移到MAUI的完整实现方案:


1. 自定义Entry控件(跨平台)

保留核心退格事件逻辑,简化委托定义:

namespace Test.CustomControls;

public class CustomEntry : Entry
{
    // 退格键按下事件
    public event EventHandler BackspacePressed;

    // 触发事件的方法
    public void OnBackspacePressed()
    {
        BackspacePressed?.Invoke(this, EventArgs.Empty);
    }
}

2. Android平台Handler实现

替代原EntryRenderer,通过Handler处理键盘事件:

namespace Test.Platforms.Android;

public class CustomEntryHandler : EntryHandler
{
    public override bool DispatchKeyEvent(KeyEvent e)
    {
        // 检测退格键按下且输入框为空时触发事件
        if (e.Action == KeyEventActions.Down && e.KeyCode == Keycode.Del)
        {
            if (string.IsNullOrWhiteSpace(Control.Text) && VirtualView is CustomEntry customEntry)
            {
                customEntry.OnBackspacePressed();
            }
        }
        return base.DispatchKeyEvent(e);
    }
}

在MauiProgram.cs中注册Handler:

builder.ConfigureMauiHandlers(handlers =>
{
#if ANDROID
    handlers.AddHandler<CustomEntry, CustomEntryHandler>();
#endif
});

3. iOS平台Handler实现

自定义UITextField检测退格操作,通过Handler关联到自定义控件:

namespace Test.Platforms.iOS;

public class CustomEntryHandler : EntryHandler
{
    protected override void ConnectHandler(UITextField platformView)
    {
        base.ConnectHandler(platformView);
        
        // 替换为自定义退格检测文本框
        var customTextField = new BackspaceDetectingTextField();
        customTextField.DeleteBackwardPressed += OnDeleteBackward;
        
        // 同步原Entry属性(按需添加更多属性)
        customTextField.Text = VirtualView.Text;
        customTextField.KeyboardType = UIKeyboardType.NumberPad;
        customTextField.TextAlignment = UITextAlignment.Center;
        
        SetNativeControl(customTextField);
    }

    private void OnDeleteBackward(object sender, EventArgs e)
    {
        // 输入框为空时触发退格事件
        if (string.IsNullOrWhiteSpace(VirtualView.Text) && VirtualView is CustomEntry customEntry)
        {
            customEntry.OnBackspacePressed();
        }
    }

    protected override void DisconnectHandler(UITextField platformView)
    {
        if (platformView is BackspaceDetectingTextField customTextField)
        {
            customTextField.DeleteBackwardPressed -= OnDeleteBackward;
        }
        base.DisconnectHandler(platformView);
    }
}

// 自定义UITextField,捕获退格操作
public class BackspaceDetectingTextField : UITextField
{
    public event EventHandler DeleteBackwardPressed;

    public override void DeleteBackward()
    {
        base.DeleteBackward();
        DeleteBackwardPressed?.Invoke(this, EventArgs.Empty);
    }
}

在MauiProgram.cs中注册iOS Handler:

builder.ConfigureMauiHandlers(handlers =>
{
#if IOS
    handlers.AddHandler<CustomEntry, CustomEntryHandler>();
#endif
});

4. 使用示例(PIN输入页面)

在XAML中放置4个自定义输入框,后台代码处理焦点切换逻辑:

XAML代码

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:custom="clr-namespace:Test.CustomControls"
             x:Class="Test.PinEntryPage">
    <StackLayout Orientation="Horizontal" Spacing="15" HorizontalOptions="Center" VerticalOptions="Center">
        <custom:CustomEntry x:Name="Pin1" MaxLength="1" Keyboard="Numeric" WidthRequest="60" HorizontalTextAlignment="Center"/>
        <custom:CustomEntry x:Name="Pin2" MaxLength="1" Keyboard="Numeric" WidthRequest="60" HorizontalTextAlignment="Center"/>
        <custom:CustomEntry x:Name="Pin3" MaxLength="1" Keyboard="Numeric" WidthRequest="60" HorizontalTextAlignment="Center"/>
        <custom:CustomEntry x:Name="Pin4" MaxLength="1" Keyboard="Numeric" WidthRequest="60" HorizontalTextAlignment="Center"/>
    </StackLayout>
</ContentPage>

后台代码

namespace Test;

public partial class PinEntryPage : ContentPage
{
    private List<CustomEntry> _pinEntries;

    public PinEntryPage()
    {
        InitializeComponent();
        _pinEntries = new List<CustomEntry> { Pin1, Pin2, Pin3, Pin4 };

        // 绑定文本变化和退格事件
        foreach (var entry in _pinEntries)
        {
            entry.TextChanged += OnPinTextChanged;
            entry.BackspacePressed += OnPinBackspacePressed;
        }
    }

    // 输入字符后自动跳转到下一个输入框
    private void OnPinTextChanged(object sender, TextChangedEventArgs e)
    {
        if (sender is CustomEntry currentEntry && !string.IsNullOrEmpty(e.NewTextValue))
        {
            var index = _pinEntries.IndexOf(currentEntry);
            if (index < _pinEntries.Count - 1)
            {
                _pinEntries[index + 1].Focus();
            }
        }
    }

    // 空输入框按退格时跳转到上一个输入框
    private void OnPinBackspacePressed(object sender, EventArgs e)
    {
        if (sender is CustomEntry currentEntry)
        {
            var index = _pinEntries.IndexOf(currentEntry);
            if (index > 0)
            {
                _pinEntries[index - 1].Focus();
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Thanos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 19:40:06