MvvmCross not updating value when I remove all content from the EditText

I'm developing an app for Android using Xamarin with MvvmCross. In my axml, I have a EditText defined:

<EditText
    local:MvxBind="Text PorcentagemDesconto"
    android:inputType="number"
    android:layout_width="1dp"
    android:layout_weight="0.3"
    android:layout_height="wrap_content"
    android:hint="%" />

The PorcentagemDesconto field is declared this way:

private decimal? _porcentagemDesconto;
public decimal? PorcentagemDesconto
{
    get { return _porcentagemDesconto; }
    set
    {
        _porcentagemDesconto = value;
    }
}

Let's say that I insert the value 256 on the EditText. Then, I insert a breakpoint on the set method of the property, an then, remove all the digits (press the backspace 3 times), the breakpoint will be hit only 2 times, leaving the private variable with an undesired value of 2.

There is some workaround for this or am I doing something wrong here?

Upvotes: 2

Views: 359

Answers (1)

Sven-Michael St&#252;be
Sven-Michael St&#252;be

Reputation: 14760

This is because the value conversion fails. If you have your debugger attached, you will see something like this in the debug output:

MvxBind:Error: 47,35 SetValue failed with exception - ArgumentException: Object of type 'System.String' cannot be converted to type 'System.Nullable`1[System.Decimal]'.
03-15 22:11:40.939 I/mono-stdout(25671): MvxBind:Error: 47,35 SetValue failed with exception - ArgumentException: Object of type 'System.String' cannot be converted to type 'System.Nullable`1[System.Decimal]'.
      at System.RuntimeType.CheckValue (System.Object value, System.Reflection.Binder binder, System.Globalization.CultureInfo culture, BindingFlags invokeAttr) [0x00062] in /Users/builder/data/lanes/1196/e79c13cd/source/mono/mcs/class/corlib/ReferenceSources/RuntimeType.cs:131 
  at System.Reflection.MonoMethod.ConvertValues (System.Reflection.Binder binder, System.Object[] args, System.Reflection.ParameterInfo[] pinfo, System.Globalization.CultureInfo culture, BindingFlags invokeAttr) [0x0007f] in /Users/builder/data/lanes/1196/e79c13cd/source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:335 
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00014] in /Users/builder/data/lanes/1196/e79c13cd/source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:283 
  at System.Reflection.MonoProperty.SetValue (System.Object obj, System.Object value, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] index, System.Globalization.CultureInfo culture) [0x0006a] in /Users/builder/data/lanes/1196/e79c13cd/source/mono/mcs/class/corlib/System.Reflection/MonoProperty.cs:445 
  at System.Reflection.PropertyInfo.SetValue (System.Object obj, System.Object value, System.Object[] index) [0x00000] in /Users/builder/data/lanes/1196/e79c13cd/source/mono/mcs/class/corlib/System.Reflection/PropertyInfo.cs:111 

The important part of the message is

Object of type 'System.String' cannot be converted to type 'System.Nullable`1[System.Decimal]'.

You can solve this issue by using a value converter in your core library

public class NullableValueConverter : MvxValueConverter
{
    public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value;
    }

    public override object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (string.IsNullOrEmpty(value?.ToString()))
            return null;

        return value;
    }
}

And bind your value like

<EditText
    local:MvxBind="Text PorcentagemDesconto, Converter=Nullable"
    android:inputType="number"
    android:layout_width="1dp"
    android:layout_weight="0.3"
    android:layout_height="wrap_content"
    android:hint="%" />

Upvotes: 2

Related Questions