Android 的 DatePicker API 非常恶心……
但是,绑定它应该很容易:)
我要做的是添加一个自定义控件和一个自定义绑定。
有关自定义 Droid 控件的一些帮助,请参阅
有关自定义绑定的其他一些问题,请参阅
以及来自http://slodge.blogspot.co.uk/p/mvvmcross-quicklist.html的其他链接
Android DatePicker
API 显然是由 Kermit 在停机期间编写的,因此对于DatePicker
,我可能建议您实现一个EmiDatePicker
继承DatePicker
并整理 API 的 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 在 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)