MvvmCross将小数绑定到MvxDialogFragment上的文本字段

时间:2018-04-05 18:41:44

标签: android xamarin xamarin.android mvvmcross

我有一个MvxDialogFragment,我用它来弹出一个对话框并要求一个带小数位的数字输入。如果我只是绑定到Text事件,那么每次键入一个数字时它会格式化数字,而下一个数字会出现在错误的位置。即。

您想输入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触发时,视图已被处理掉,因此我无法设置焦点并将值刷新到字段。有一个更好的方法吗?是否有一个事件我可以在View或ViewModel中依赖于对话框关闭但在View被释放之前发生的事件?

1 个答案:

答案 0 :(得分:0)

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

我无法通过我的实施复制下一个错误的数字,可以查看here