[英]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.