Android MVVM将十进制交叉绑定到MvxDialogFragment上的文本字段

Android MVVM将十进制交叉绑定到MvxDialogFragment上的文本字段,android,xamarin,xamarin.android,mvvmcross,Android,Xamarin,Xamarin.android,Mvvmcross,我有一个MvxDialogFragment,我用它弹出一个对话框,要求输入一个带小数点的数字条目。如果我只是绑定到文本事件,那么每次键入一个数字时,它都会格式化该数字,而下一个数字出现在错误的位置。i、 e 你想输入10.00吗 你输入1 1.00出现在现场 您可以键入0 01.00出现在现场 出于这个原因,我创建了一个名为FocusText的绑定,这是Stuart多年前为我编写的 public class MvxEditTextFocusBinding : MvxConvertingTarge

我有一个MvxDialogFragment,我用它弹出一个对话框,要求输入一个带小数点的数字条目。如果我只是绑定到文本事件,那么每次键入一个数字时,它都会格式化该数字,而下一个数字出现在错误的位置。i、 e

你想输入10.00吗

你输入1

1.00出现在现场

您可以键入0

01.00出现在现场

出于这个原因,我创建了一个名为FocusText的绑定,这是Stuart多年前为我编写的

public class MvxEditTextFocusBinding : MvxConvertingTargetBinding 
{
    protected EditText EditText
    {
        get { return (EditText)Target; }
    }

    private bool _subscribed;

    public MvxEditTextFocusBinding(EditText view)
        : base(view)
    {
    }

    protected override void SetValueImpl(object target, object value)
    {
        var editText = EditText;
        if (editText == null)
            return;

        value = value ?? string.Empty;
        editText.Text = value.ToString();
    }

    public override MvxBindingMode DefaultMode
    {
        get { return MvxBindingMode.TwoWay; }
    }

    public override void SubscribeToEvents()
    {
        var editText = EditText;
        if (editText == null)
            return;

        editText.FocusChange += HandleFocusChange;
        _subscribed = true;
    }

    private void HandleFocusChange(object sender, View.FocusChangeEventArgs e)
    {
        var editText = EditText;
        if (editText == null)
            return;

        if (!e.HasFocus)
            FireValueChanged(editText.Text);
    }

    public override Type TargetType
    {
        get { return typeof(string); }
    }

    protected override void Dispose(bool isDisposing)
    {
        if (isDisposing)
        {
            var editText = EditText;
            if (editText != null && _subscribed)
            {
                editText.FocusChange -= HandleFocusChange;
                _subscribed = false;
            }
        }
        base.Dispose(isDisposing);
    }
}
我对该字段的AXML如下所示:

<EditText
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    style="@style/TableEditText"
    android:inputType="number"
    local:MvxBind="FocusText Amount, Converter=DecimalToStringConverter, ConverterParameter=2"
    android:id="@+id/txtAmount" />
public class DecimalToStringConverter : IMvxValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, CultureInfo language)
    {
        if ((value != null) && (value.GetType() == typeof(decimal)))
        {
            decimal tmp = (decimal)value;
            int Decimals;
            if (parameter != null && int.TryParse(parameter.ToString(), out Decimals))
            {
                string format = "f" + Decimals.ToString();
                return tmp.ToString(format);
            }
            else
                return tmp.ToString();
        }
        return "";
    }

    // ConvertBack is not implemented for a OneWay binding.
    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo language)
    {
        decimal tmp;
        if (decimal.TryParse(value.ToString(), out tmp))
            return tmp;
        return null;
    }
}

这会使EditText在设置值之前等待,直到失去焦点。在常规活动中,我有一个隐藏字段,当按下后退按钮时,我会将焦点设置为该字段,以确保绑定将值刷新到该字段。在MvxDialogFragment中,没有反压事件。当OnPause或OnDismiss激发时,视图已经被释放,因此我无法设置焦点并将值刷新到字段。有更好的方法吗?对话框关闭时,但在视图被释放之前,视图或视图模型中是否会发生我可以依赖的事件?

我建议您更改EditText xml,以指定“numberDecimal”作为输入类型;这将允许您直接绑定到viewModel中的decimal属性。这样就不需要字符串到十进制的转换器了


我无法用我的实现复制错误位置的下一个数字,可以查看它

您可以不使用转换器直接绑定到数字属性吗?我认为这就是转换器的用途。是的,正如您在上面的github链接中所看到的,我直接绑定到numeric属性。如果您正在做一些自定义的事情,而不是作为默认值由mvvmcross处理,那么您只需要编写自定义转换器。我可以看出,直接绑定到数值属性是有效的。问题是,如果您说键入一个数字并将其退格,当字段为空时,它不会将值设置为0。你知道怎么处理吗?