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

如何让.NET MAUI数字输入框同时接受点和逗号作为小数分隔符?

让数字输入框同时支持点和逗号作为小数分隔符的解决方案

在德语环境下,系统默认的Numeric键盘只允许逗号作为小数分隔符,要实现同时接受点和逗号,可以通过以下几种方式处理:

方法一:自定义Entry行为(Behavior)实时处理输入

这种方式能实时过滤和转换输入内容,体验最好,且跨平台通用。

1. 创建DecimalSeparatorBehavior类

using Xamarin.Forms;
using System.Linq;

public class DecimalSeparatorBehavior : Behavior<Entry>
{
    protected override void OnAttachedTo(Entry bindable)
    {
        base.OnAttachedTo(bindable);
        bindable.TextChanged += OnTextChanged;
    }

    protected override void OnDetachingFrom(Entry bindable)
    {
        base.OnDetachingFrom(bindable);
        bindable.TextChanged -= OnTextChanged;
    }

    private void OnTextChanged(object sender, TextChangedEventArgs e)
    {
        if (sender is not Entry entry || string.IsNullOrEmpty(e.NewTextValue)) return;

        string newText = e.NewTextValue;
        // 只保留数字、点、逗号
        char[] allowedChars = "0123456789.,".ToCharArray();
        newText = new string(newText.Where(c => allowedChars.Contains(c)).ToArray());

        // 处理多个分隔符的情况,统一转换为逗号(也可根据需求改为点)
        int dotIndex = newText.IndexOf('.');
        int commaIndex = newText.IndexOf(',');

        if (dotIndex != -1 && commaIndex != -1)
        {
            // 同时存在点和逗号时,把点全部转成逗号
            newText = newText.Replace('.', ',');
        }

        // 确保只有一个分隔符
        int separatorCount = newText.Count(c => c == ',');
        if (separatorCount > 1)
        {
            int firstSeparator = newText.IndexOf(',');
            newText = newText.Remove(firstSeparator + 1).Replace(",", "") 
                      + "," 
                      + newText.Substring(firstSeparator + 1).Replace(",", "");
        }

        entry.Text = newText;
    }
}

2. 在XAML中引用Behavior

记得先添加命名空间引用(把你的命名空间替换成实际的类所在命名空间):

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:你的命名空间"
             x:Class="你的页面类">

    <Entry Text="{Binding LVK}" Placeholder="LVK">
        <Entry.Behaviors>
            <local:DecimalSeparatorBehavior />
        </Entry.Behaviors>
    </Entry>

</ContentPage>

方法二:在ViewModel属性中处理转换

如果不想用Behavior,也可以在绑定的属性setter里做转换,不过输入时会有轻微延迟:

private string _lvk;
public string LVK
{
    get => _lvk;
    set
    {
        if (string.IsNullOrEmpty(value))
        {
            _lvk = value;
            OnPropertyChanged();
            return;
        }

        // 把输入的点转成逗号
        string processedValue = value.Replace('.', ',');
        // 移除多余的逗号
        int commaCount = processedValue.Count(c => c == ',');
        if (commaCount > 1)
        {
            int firstComma = processedValue.IndexOf(',');
            processedValue = processedValue.Remove(firstComma + 1).Replace(",", "") 
                             + "," 
                             + processedValue.Substring(firstComma + 1).Replace(",", "");
        }

        _lvk = processedValue;
        OnPropertyChanged();
    }
}

XAML里可以保留Keyboard="Numeric",但输入点后会在属性更新时自动转成逗号。

方法三:自定义平台渲染器(深度定制)

如果需要更贴合系统键盘的体验,可以针对Android和iOS分别写自定义渲染器,修改键盘的允许输入字符。以Android为例:

using Android.Content;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using System.Linq;

[assembly: ExportRenderer(typeof(Entry), typeof(CustomNumericEntryRenderer))]
namespace 你的命名空间.Droid
{
    public class CustomNumericEntryRenderer : EntryRenderer
    {
        public CustomNumericEntryRenderer(Context context) : base(context) { }

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
            if (Control == null) return;

            // 设置输入类型为数字+小数
            Control.InputType = Android.Text.InputTypes.ClassNumber | Android.Text.InputTypes.NumberFlagDecimal;
            // 添加自定义输入过滤器
            Control.SetFilters(new Android.Text.InputFilter[] { new DecimalInputFilter() });
        }
    }

    public class DecimalInputFilter : Android.Text.InputFilter
    {
        public override ICharSequence FilterFormatted(ICharSequence source, int start, int end, Android.Text.ISpanned dest, int dstart, int dend)
        {
            string newText = dest.ToString().Insert(dstart, source.ToString());
            char[] allowedChars = "0123456789.,".ToCharArray();
            string filtered = new string(newText.Where(c => allowedChars.Contains(c)).ToArray());

            // 处理多个分隔符
            int separatorCount = filtered.Count(c => c == '.' || c == ',');
            if (separatorCount > 1)
            {
                int firstSeparator = filtered.IndexOfAny(new char[] { '.', ',' });
                filtered = filtered.Remove(firstSeparator + 1).Replace(".", "").Replace(",", "") 
                          + filtered[firstSeparator] 
                          + filtered.Substring(firstSeparator + 1).Replace(".", "").Replace(",", "");
            }

            return new Java.Lang.String(filtered);
        }
    }
}

iOS的渲染器逻辑类似,需要修改键盘的输入规则,这里就不展开了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 21:24:49