Android MVVM将十进制交叉绑定到MvxDialogFragment上的文本字段
我有一个MvxDialogFragment,我用它弹出一个对话框,要求输入一个带小数点的数字条目。如果我只是绑定到文本事件,那么每次键入一个数字时,它都会格式化该数字,而下一个数字出现在错误的位置。i、 e 你想输入10.00吗 你输入1 1.00出现在现场 您可以键入0 01.00出现在现场 出于这个原因,我创建了一个名为FocusText的绑定,这是Stuart多年前为我编写的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
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。你知道怎么处理吗?