is there a way to achieve a PayPal like 'decimal-first' entry in Xamarin Forms?
I hope the screenshot is self explanatory. I basically want an instantaneous division of the input by 100. For an input of e.g. 3,85 I want it shown as
0,03
0,38
3,85
Is there a good way to implement this in Xamarin Forms?
Tanks in advance
CodePudding user response:
This can be achieved by TextChanged
event.
Here's the code below for your reference:
Xaml:
<Entry
Keyboard="Numeric"
TextChanged="Entry_TextChanged"
/>
Code behind:
private void Entry_TextChanged(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;
}
}
CodePudding user response:
I've been thinking about your question and got something you may want to.
Try to bind your textBox with property Text="{Binding InputValue}. Then implement INotifyPropertyChanged interface by typing : INotifyPropertyChanged
to your main class.
Create public event PropertyChangedEventHandler
named PropertyChanged and add required:
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Don't forget to set property, by typing InputValue = 0.00M add DataContext = this below InitializeComponent(); too.
It's very important to create fullprop like this:
private decimal inputValue;
public decimal InputValue
{
get { return inputValue; }
set
{
inputValue = value;
OnPropertyChanged("InputValue");
}
}
Now you have to set your textBox to be ReadOnly and add KeyDown event:
private void InputPriceTextBox_KeyDown(object sender, KeyEventArgs e)
{
int num = 0;
string stringVal = e.Key.ToString();
if (stringVal.Length > 1)
{
if (stringVal.Contains("NumPad"))
{
num = Convert.ToInt32(stringVal.Substring(6));
}
else if (stringVal.Contains("D"))
{
num = Convert.ToInt32(stringVal.Substring(1));
}
else
{
return;
}
if (InputValue == 0.00M)
{
InputValue = 0.00M (decimal)num / 100;
}
else
{
InputValue *= 10;
InputValue = (decimal)num / 100;
}
}
}
It works for me, try it yourself!