2

如何在 Mono For Android 中将 Time - & /DatePicker 与 MVVMCross 绑定?

  <TimePicker
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

  <DatePicker
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

以及后面的属性有哪些类型?对于日期,可能是日期时间和时间选择器?或者我们这里有一个属性foreach数字,例如日期:年 (INT)、月 (INT) 和日 (INT) = 3 个属性?

卡在这个,没有找到任何例子..

帮助表示赞赏

4

1 回答 1

1

Android 的 DatePicker API 非常恶心……

但是,绑定它应该很容易:)

我要做的是添加一个自定义控件和一个自定义绑定。


有关自定义 Droid 控件的一些帮助,请参阅

有关自定义绑定的其他一些问题,请参阅

以及来自http://slodge.blogspot.co.uk/p/mvvmcross-quicklist.html的其他链接


Android DatePickerAPI 显然是由 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)

于 2013-02-12T11:27:51.390 回答