Forum Xamarin.Forms

Entry binding Decimal

I'm a problem, in my view Model have decimal property

private decimal number1;
public decimal Number1{
            get{ return number1;}
            set{
                number1 = value;
                this.Notify();
            }
        }

xaml

<Entry Placeholder="Value Number" 
                       Keyboard="Numeric"
                       Text="{Binding Number1}"/>

but when I'm binding my entry displays this message: "Binding: can not be converted to type 'System.Decimal"

Best Answers

Answers

  • IlmanSultygovIlmanSultygov USMember ✭✭
    edited February 2016

    how do the conversion?

  • ST.7899ST.7899 USMember ✭✭
    edited November 2017

    there is still a problem if you use entries .
    Assume you have an entry that the user can enter an amount inside and want to format thousands by comma e.g 1,028.55
    The entry will not able to handle it because there is not UpdateSourceTrigger LostFocus to format it after the user ends/ complete the amount.
    If you try to solve this by text change or a converter you will notice that while you are typing the cursor is always at the end therefore what ever you type is useless.
    I try several ways now but without any success .
    I try the event Completed on the Entry: Works only if you press the enter on the keyboard but if you just tab out of the entry then the amount remains affected 1028.50
    I Try LostFocus Not work because when you enter on the entry and double tab the amount to select all and enter a new amount then the Entry shortcut appears "CUT,COPY,PASTE" and the lostfocus event fires which is something that you don't want.

    one solution I think but is no good is to have an edit button next to the amount then show somehow a dialog with empty entry , entering the amount and then formatting the new amount as you want . this way you leave your entry untouched with the StringFormat you want

    If anyone has a better solution for this problem please share.

  • Eric_LiraEric_Lira USMember ✭✭✭

    I came across this problem today and my solution was to create a custom Entry where I could bind my ViewModel property to another property other then the Entry Text.
    In this case, I used Focused and Unfocused events to convert values between Text and my NumericValue property. It worked pretty well for me but you can probably simplify a bit.

    Here is my code. Let me know if someone has a better solution!

    public class NumericTextBox : Entry
    {
    
        #region Bindables
        public static readonly BindableProperty NumericValueProperty = BindableProperty.Create(
            "NumericValue",
            typeof(decimal?),
            typeof(NumericTextBox),
            null,
            BindingMode.TwoWay,
            propertyChanged: (bindable, oldValue, newValue) =>
            {
                SetDisplayFormat((NumericTextBox)bindable);
            }
        );
    
        public static readonly BindableProperty NumericValueFormatProperty = BindableProperty.Create(
            "NumericValueFormat",
            typeof(string),
            typeof(NumericTextBox),
            "N0",
            BindingMode.TwoWay,
            propertyChanged: (bindable, oldValue, newValue) =>
            {
                SetDisplayFormat((NumericTextBox)bindable);
            }
        );
        #endregion
    
        #region Constructor
        public NumericTextBox()
        {
            Keyboard = Keyboard.Numeric;
            Focused += OnFocused;
            Unfocused += OnUnfocused;
        }
        #endregion
    
        #region Events
        private void OnFocused(object sender, FocusEventArgs e)
        {
            SetEditFormat(this);
        }
    
        private void OnUnfocused(object sender, FocusEventArgs e)
        {
            var numberFormant = CultureInfo.InvariantCulture.NumberFormat;
            var _text = Text.Replace(numberFormant.NumberGroupSeparator, string.Empty).Replace(numberFormant.NumberDecimalSeparator, ".");
    
            if (decimal.TryParse(_text, NumberStyles.Number, CultureInfo.InvariantCulture, out decimal numericValue))
            {
                int round = Convert.ToInt32(NumericValueFormat.Substring(1));
                NumericValue = Math.Round(numericValue, round);
            }
            else
            {
                NumericValue = null;
            }
    
            SetDisplayFormat(this);
        }
        #endregion
    
        #region Properties
        public decimal? NumericValue
        {
            get { return (decimal?)GetValue(NumericValueProperty); }
            set { SetValue(NumericValueProperty, value); }
        }
    
        public string NumericValueFormat
        {
            get { return (string)GetValue(NumericValueFormatProperty) ?? "N0"; }
            set
            {
                var _value = string.IsNullOrWhiteSpace(value) ? "N0" : value;
                SetValue(NumericValueFormatProperty, value);
            }
        }
        #endregion
    
        #region Methods
        private static void SetDisplayFormat(NumericTextBox textBox)
        {
            if (textBox.NumericValue.HasValue)
            {
                textBox.Text = textBox.NumericValue.Value.ToString(textBox.NumericValueFormat, CultureInfo.DefaultThreadCurrentCulture);
            }
            else
            {
                textBox.Text = string.Empty;
            }
        }
    
        private static void SetEditFormat(NumericTextBox textBox)
        {
            if (textBox.NumericValue.HasValue)
            {
                var numberFormant = CultureInfo.InvariantCulture.NumberFormat;
                textBox.Text = textBox.NumericValue.Value.ToString(textBox.NumericValueFormat, CultureInfo.InvariantCulture).Replace(numberFormant.NumberGroupSeparator, string.Empty);
            }
            else
            {
                textBox.Text = string.Empty;
            }
        }
        #endregion
    }
    
  • centrolutionscentrolutions USMember ✭✭

    @Eric_Lira thanks for the code! It worked great for me.

  • Eric_LiraEric_Lira USMember ✭✭✭

    Glad to help @centrolutions!

Sign In or Register to comment.