繁体   English   中英

Xamarin.forms 条目小数点分隔符在不同的 CultureInfo 上不能正常工作

[英]Xamarin forms Entry decimal separator does not work properly on different CultureInfo

我在 xaml 中有一个条目:

<Entry Grid.Column="1" Grid.RowSpan="1"
                                   FontAttributes="None" FontSize="Large"
                                   IsPassword="False" Keyboard="Numeric"
                                   HorizontalTextAlignment="Center" VerticalOptions="StartAndExpand"
                                   Text="{Binding MyNumber}"
                                   TextColor="{Binding PropertyTextColor, Converter={StaticResource StringToColorConverter}}"
                                   Completed="Entry_Completed"/>

当我拥有美国文化信息时,一切正常,但当文化信息更改时,我无法为小数输入输入逗号或点分隔符。 例如,当我键入 5 并输入“,”并键入 5 时,该值将转换为 55。我尝试更改当前线程的区域性信息,但没有帮助。

    private decimal _myNumber;
    public decimal MyNumber
    {
        get
        {
            return myNumber;
        }
        set
        {
            System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
            if (_myNumber != value)
            {
                if (IsDivisible)
                    //_myNumber = Convert.ToDecimal(Math.Round(value, 2).ToString(), new CultureInfo("pl-PL"));
                    _ = decimal.TryParse(value.ToString(), NumberStyles.Any, new CultureInfo("pl-PL"), out _count);
                else
                    _ = decimal.TryParse(value.ToString(), NumberStyles.Any, new CultureInfo("pl-PL"), out _count);
                 // _myNumber = Convert.ToDecimal(Math.Round(value, 0).ToString(), new CultureInfo("pl-PL"));

                OnPropertyChanged(nameof(Count));
            }
        }
    }

有什么办法可以解决这个问题吗? 因为据我了解,此问题与三星配置或设置有关,并且在 Xamarin 中是一个很常见的问题。

就我而言,我最终需要强制将点作为每种文化的小数点分隔符。 为了打印点,我还需要为 Entry 创建一个自定义渲染器,以便重新设置 InputTypes 标志。

如果这听起来像您可能想要遵循的方式,请继续阅读。

以下是一个示例最小应用程序,用于演示如何在 Android 中为 Xamarin.Forms 强制使用点作为小数点分隔符

强制点作为小数分隔符

首先我们要告诉App,无论使用什么文化,点都必须作为小数点分隔符:

public App()
{
    CultureInfo customCulture = (CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
    customCulture.NumberFormat.NumberDecimalSeparator = ".";

    System.Threading.Thread.CurrentThread.CurrentCulture = customCulture;

    InitializeComponent();

    MainPage = new MainPage();
}

重新设置输入类型

在您的 Xamarin.Forms 共享项目上创建一个 CustomEntry:

using Xamarin.Forms;

namespace EntryDecimal
{
    public class MyCustomEntry : Entry
    {
    }
}

然后在 Android 添加自定义渲染器。为此,只需将新的 class 添加到名为 AndroidCustomEntryRenderer.cs 的 Android 项目,其内容如下:

using System.ComponentModel;

using Android.Widget;

using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

using Android.Text.Method;
using Android.Content;
using EntryDecimal.Droid;
using EntryDecimal;

[assembly: ExportRenderer(typeof(MyCustomEntry), typeof(AndroidCustomEntryRenderer))]
namespace EntryDecimal.Droid
{
    public class AndroidCustomEntryRenderer : EntryRenderer
    {
        private MyCustomEntry element;
        private EditText native;

        public AndroidCustomEntryRenderer(Context context) : base(context)
        { }

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);

            //Java.Text.DecimalFormatSymbols.Instance.DecimalSeparator = '.';

            element = (MyCustomEntry)Element ?? null;
            native = Control as EditText;

            UpdateKeyboard();
        }


        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (Control == null) return;

            else if (e.PropertyName == InputView.KeyboardProperty.PropertyName)
                UpdateKeyboard();
        }

        private void UpdateKeyboard()
        {
            //Implementation of the numeric keyboard (we simply add the NumberFlagSigned)
            native = Control as EditText;

            var defaultNumericKeyboard = Android.Text.InputTypes.ClassNumber | Android.Text.InputTypes.NumberFlagDecimal;
            var correnctNumericKeyboard = Android.Text.InputTypes.ClassNumber | Android.Text.InputTypes.NumberFlagSigned | Android.Text.InputTypes.NumberFlagDecimal;

            if (native.InputType == defaultNumericKeyboard)
            {
                native.InputType =
                Android.Text.InputTypes.ClassNumber |
                Android.Text.InputTypes.NumberFlagSigned |
                Android.Text.InputTypes.NumberFlagDecimal;
                native.KeyListener = DigitsKeyListener.GetInstance(string.Format("7890.-"));
            }
            else if (native.InputType == correnctNumericKeyboard)
            {
                // Even though in the next line the InputType is set to the same it is already set, this seems to 
                // fix the problem with the decimal separator: Namely, a local other than english is set, the point 
                // does not have any effect in the numeric keyboard. Re-setting the InputType seems to fix this.
                native.InputType =
                Android.Text.InputTypes.ClassNumber |
                Android.Text.InputTypes.NumberFlagSigned |
                Android.Text.InputTypes.NumberFlagDecimal;
            }
        }
        
    }
}

最后消费这个:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:EntryDecimal"
             x:Class="EntryDecimal.MainPage">

    <StackLayout>
        <local:MyCustomEntry x:Name="MyEntry"  Keyboard="Numeric"
               WidthRequest="150"
               HorizontalOptions="CenterAndExpand"
               VerticalOptions="CenterAndExpand"
                             Completed="MyCustomEntry_Completed"/>
    </StackLayout>

</ContentPage>

这个最小的空白应用程序在我这边工作正常,接受点作为任何文化的小数点分隔符(比如 de [german],其中小数点分隔符是“,”)。

希望这有效!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM