Xamarin.Forms条目带有自动千位和小数分隔符

时间:2016-08-04 15:00:07

标签: xamarin decimal xamarin.forms currency

我有一个带有数字键盘的Xamarin.Forms条目,它代表一个pt-BR REAL货币(999.999,99)。当我在数字键盘中输入数字时,需要在我输入时自动添加逗号(表示十进制)和点(代表千)。

为了实现这一目标,Xamarin.Forms在所有平台上工作的最佳实践/设计模式是什么?

2 个答案:

答案 0 :(得分:0)

无需创建自定义渲染器。

我建议继承Entry并订阅TextChanged event。 在那里,您将解析并重新格式化当前文本并更新Text属性。

答案 1 :(得分:0)

诀窍是使用TextChanged事件。第一步,我从字符串中删除了$,以便可以解析新的文本值。如果解析失败,则意味着用户添加了一个非数字字符,我们将还原为旧文本。

接下来,我们检测用户是否将新数字添加到小数点的右边(例如1.532)。如果是这样,我们将小数点向右移动*10。对DELETION执行相反的操作。

哦,当我们初始化数字时几乎忘了!输入的第一位数字是整数,因此我们* 100以确保输入的第一位数字以小数开头。

一旦十进制正确,我们将使用num.ToString("C");

显示它

工作示例: enter image description here

xaml:

<Entry                 
    Keyboard="Numeric"
    TextChanged="OnFinancialTextChanged"
    Placeholder="$10.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;
    }
}