Android 的 DatePicker API 实在是太恶心了……
但是,绑定它应该很容易:)
我要做的是添加自定义控件和自定义绑定。
有关自定义 Droid 控件的帮助,请参阅
有关自定义绑定的其他一些问题,请参阅
以及来自http://slodge.blogspot.co.uk/p/mvvmcross-quicklist.html的其他链接
Android DatePicker API 显然是由 Kermit 在停机期间编写的,因此对于 DatePicker,我可能建议您实现一个继承自 DatePicker 的 EmiDatePicker 并整理 API。
这可以提供单个属性和单个事件:
private bool _initialised;
public DateTime Value
{
get
{
return new DateTime(Year, Month.ToCLRMonthNumber(), DayOfMonth);
}
set
{
if (_initialised)
{
UpdateDate(value.Year, value.Month.ToJavaMonthNumber(), value.DayOfMonth);
}
else
{
_initialised = true;
Init(value.Year, value.Month.ToJavaMonthNumber(), value.DayOfMonth, new EmiListener(this));
}
}
}
public event EventHandler ValueChanged;
地点:
-
ToJavaMonthNumber、ToCLRMonthNumber 是 +1、-1 修复的解决方法 - 请参阅 MonthDisplayHelper.NumberOfDaysInMonth returning incorrect value in MonoDroid
-
EmiListener 是 IOnDateChangeListener 的一个简单实现,用于触发 ValueChanged - 类似于:
public class EmiListener : Java.Lang.Object, DatePicker.IOnDateChangedListener
{
private EmiDatePicker _datePicker;
public EmiListener(EmiDatePicker datePicker)
{
_datePicker = datePicker;
}
public void OnDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth)
{
_datePicker.InternalSetValueAndRaiseChanged(new DateTime(year, monthOfYear.ToCLRMonth(), dayOfMonth));
}
}
完成后...接下来的代码步骤将是添加绑定 - 这很简单:
public class EmiDatePickerValueTargetBinding : MvxPropertyInfoTargetBinding<EmiDatePicker>
{
public EmiDatePickerValueTargetBinding(object target, PropertyInfo targetPropertyInfo)
: base(target, targetPropertyInfo)
{
var datePicker = View;
if (datePicker == null)
{
MvxBindingTrace.Trace(MvxTraceLevel.Error, "Error - datePicker is null in EmiDatePickerValueTargetBinding");
}
else
{
datePicker.ValueChanged += DatePickerOnValueChanged;
}
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.TwoWay; }
}
private void DatePickerOnValueChanged(object sender, EventArgs args)
{
FireValueChanged(View.Value);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
{
var datePicker = View;
if (datePicker != null)
{
datePicker.ValueChanged -= DatePickerOnValueChanged;
}
}
}
}
要注册此绑定,只需将其添加到应用的设置类中即可:
protected override void FillTargetFactories(Cirrious.MvvmCross.Binding.Interfaces.Bindings.Target.Construction.IMvxTargetBindingFactoryRegistry registry)
{
registry.RegisterFactory(new MvxSimplePropertyInfoTargetBindingFactory(
typeof (EmiDatePickerValueTargetBinding), typeof (EmiDatePicker), "Value"));
base.FillTargetFactories(registry);
}
此时,您终于可以在 XML 中使用 EmiDatePicker - 尽管为了节省输入,我建议使用 XML 缩写 - http://slodge.blogspot.co.uk/2013/02/abbreviated-namespaces-for-your-custom.html
要做TimePicker...同样的,但我会把它留给你...
上面的代码会有错别字 - 请编辑更正它。
如果这段代码有效......并且因为它是很多“机械代码”,我很乐意看到它开源(甚至可能推回 MvvmCross)