【问题标题】:Bind TimePicker & DatePicker - MVVMCross (Mono For Android)绑定 TimePicker 和 DatePicker - MVVMCross(Android 单声道)
【发布时间】:2013-02-12 09:42:04
【问题描述】:

如何在 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" />

后面的属性有哪些类型?对于 Date,可能是 DateTime 和 TimePicker?或者我们这里是否有一个属性 foreach 数字,例如日期:年 (INT)、月 (INT) 和日 (INT) = 3 个属性?

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

帮助赞赏

【问题讨论】:

    标签: android datepicker xamarin.android timepicker mvvmcross


    【解决方案1】:

    Android 的 DatePicker API 实在是太恶心了……

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

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


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

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

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


    Android DatePicker API 显然是由 Kermit 在停机期间编写的,因此对于 DatePicker,我可能建议您实现一个继承自 DatePickerEmiDatePicker 并整理 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;
    

    地点:

    • ToJavaMonthNumberToCLRMonthNumber 是 +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)

    【讨论】:

    • 嗨斯图尔特!谢谢回答..我正在尝试实施您的解决方案。第二个代码有问题。 datePicker 没有方法 InternalSetValueAndRaiseChanged..
    • 我现在花了一整天的时间来实现 DatePicker 和 TimePicker.. 那里有很多问题,终于解决了。我为此创建了一个新项目(参考我的主项目)。如果您愿意,我可以将项目发送给您,因为我没有太多时间在您的库中实现该项目并将其公开。
    • 是的,请 - 如果您可以包含某种“我将其发布给您 ms-pl”或“知识共享”,这将有所帮助。
    猜你喜欢
    • 2017-05-03
    • 1970-01-01
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-02
    相关资源
    最近更新 更多