Xamarin.Forms 带有自动千位和小数点分隔符的条目
Xamarin.Forms Entry with auto thousand and decimal separator
我有一个带有数字键盘的 Xamarin.Forms 条目,它将代表 pt-BR REAL 货币 (999.999,99)。当我在数字键盘上输入数字时,逗号(代表小数)和点(代表千)需要在输入时自动添加。
为了实现这个目标,Xamarin.Forms 中适用于所有平台的最佳 practice/design 模式是什么?
无需创建自定义渲染器。
我建议继承 Entry
并订阅 TextChanged
event。
在那里你将解析和重新格式化当前文本并更新 Text
属性.
诀窍是使用 TextChanged 事件。第一步我从字符串中删除了 $ 以便我可以解析新的文本值。如果它无法解析,则意味着用户添加了一个 non-digit 字符,我们只是恢复到旧文本。
接下来,我们检测用户是否添加了一个新数字并将其添加到小数点的右边(示例 1.532)。如果是这样,我们将小数点向右移动 * 10。对删除执行相反的操作。
哦,差点忘了我们什么时候初始化数字!我们输入的第一个数字将是整数,因此我们 * 100 以确保我们输入的第一个数字以分数开头。
一旦我们得到正确的小数点,我们将使用 num.ToString("C");
显示它
工作示例:
xaml:
<Entry
Keyboard="Numeric"
TextChanged="OnFinancialTextChanged"
Placeholder=".00"
Text="{Binding RetailPrice}"/>
然后在cs
.cs:
private void OnFinancialTextChanged(object sender, TextChangedEventArgs e)
{
var entry = (Entry)sender;
var amt = e.NewTextValue.Replace("$", "");
if (decimal.TryParse(amt, out decimal num))
{
// Init our number
if(string.IsNullOrEmpty(e.OldTextValue))
{
num = num / 100;
}
// Shift decimal to right if added a decimal digit
else if (num.DecimalDigits() > 2 && !e.IsDeletion())
{
num = num * 10;
}
// Shift decimal to left if deleted a decimal digit
else if(num.DecimalDigits() < 2 && e.IsDeletion())
{
num = num / 10;
}
entry.Text = num.ToString("C");
}
else
{
entry.Text = e.OldTextValue;
}
}
我创建了这些扩展方法来帮助处理逻辑
public static class ExtensionMethods
{
public static int DecimalDigits(this decimal n)
{
return n.ToString(System.Globalization.CultureInfo.InvariantCulture)
.SkipWhile(c => c != '.')
.Skip(1)
.Count();
}
public static bool IsDeletion(this TextChangedEventArgs e)
{
return !string.IsNullOrEmpty(e.OldTextValue) && e.OldTextValue.Length > e.NewTextValue.Length;
}
}
我有一个带有数字键盘的 Xamarin.Forms 条目,它将代表 pt-BR REAL 货币 (999.999,99)。当我在数字键盘上输入数字时,逗号(代表小数)和点(代表千)需要在输入时自动添加。
为了实现这个目标,Xamarin.Forms 中适用于所有平台的最佳 practice/design 模式是什么?
无需创建自定义渲染器。
我建议继承 Entry
并订阅 TextChanged
event。
在那里你将解析和重新格式化当前文本并更新 Text
属性.
诀窍是使用 TextChanged 事件。第一步我从字符串中删除了 $ 以便我可以解析新的文本值。如果它无法解析,则意味着用户添加了一个 non-digit 字符,我们只是恢复到旧文本。
接下来,我们检测用户是否添加了一个新数字并将其添加到小数点的右边(示例 1.532)。如果是这样,我们将小数点向右移动 * 10。对删除执行相反的操作。
哦,差点忘了我们什么时候初始化数字!我们输入的第一个数字将是整数,因此我们 * 100 以确保我们输入的第一个数字以分数开头。
一旦我们得到正确的小数点,我们将使用 num.ToString("C");
工作示例:
xaml:
<Entry
Keyboard="Numeric"
TextChanged="OnFinancialTextChanged"
Placeholder=".00"
Text="{Binding RetailPrice}"/>
然后在cs
.cs:
private void OnFinancialTextChanged(object sender, TextChangedEventArgs e)
{
var entry = (Entry)sender;
var amt = e.NewTextValue.Replace("$", "");
if (decimal.TryParse(amt, out decimal num))
{
// Init our number
if(string.IsNullOrEmpty(e.OldTextValue))
{
num = num / 100;
}
// Shift decimal to right if added a decimal digit
else if (num.DecimalDigits() > 2 && !e.IsDeletion())
{
num = num * 10;
}
// Shift decimal to left if deleted a decimal digit
else if(num.DecimalDigits() < 2 && e.IsDeletion())
{
num = num / 10;
}
entry.Text = num.ToString("C");
}
else
{
entry.Text = e.OldTextValue;
}
}
我创建了这些扩展方法来帮助处理逻辑
public static class ExtensionMethods
{
public static int DecimalDigits(this decimal n)
{
return n.ToString(System.Globalization.CultureInfo.InvariantCulture)
.SkipWhile(c => c != '.')
.Skip(1)
.Count();
}
public static bool IsDeletion(this TextChangedEventArgs e)
{
return !string.IsNullOrEmpty(e.OldTextValue) && e.OldTextValue.Length > e.NewTextValue.Length;
}
}