2014-06-10 63 views
2

我使用Xamarin.iOS和MvvmCross來構建頁面視圖。我有一個UIView在DateAndTime模式中包含UIDatePicker。如果我在綁定的vm屬性中放置斷點並更改日期,則可以看到綁定的火災。如果我改變時間,但沒有更新綁定的屬性。MvvmCross:UIDatePicker時間更改不會觸發綁定

下面是代碼:

[Register("EditJobViewJobView")] 
public class EditJobView : MvxViewController 
{ 
    public new EditJobViewModel ViewModel 
    { 
     get { return (EditJobViewModel)base.ViewModel; } 
    } 

    private const float _leftMargin = 6; 
    private const float _labelHeight = 20; 
    private const float _pickerHeight = 28; 

    private readonly UIFont _labelFont = UIFont.BoldSystemFontOfSize(18f); 
    private readonly UIFont _controlFont = UIFont.SystemFontOfSize(18f); 

    private readonly UIView _paddingInsert = new UIView(new RectangleF(0, 0, 4, 0)); 

    private int _currentTop = 0; 

    public override void ViewDidLoad() 
    { 
     base.ViewDidLoad(); 

     View = new UIView() { BackgroundColor = UIColor.White }; 

     NavigationItem.SetRightBarButtonItem(new UIBarButtonItem("Save", UIBarButtonItemStyle.Bordered, 
      (sender, args) => ViewModel.OkCommand.Execute(null)), true); 

     // ios7 layout 
     if (RespondsToSelector(new Selector("edgesForExtendedLayout"))) 
      EdgesForExtendedLayout = UIRectEdge.None; 

     Title = "Edit Job"; 

     AddLabel("Start On"); 
     UIDatePicker startOnPicker; 
     var startOnView = AddDateTimeView(out startOnPicker); 

     var set = this.CreateBindingSet<EditJobView, EditJobViewModel>(); 
     set.Bind(startOnPicker).For("DateAndTime").To(vm => vm.TestStartOn); 
     set.Bind(startOnView).To(vm => vm.TestFormatted); 
     set.Apply(); 
    } 

    private void AddLabel(string caption) 
    { 
     _currentTop += 10; 
     var frame = new RectangleF(_leftMargin, _currentTop, 300, _labelHeight); 
     var label = new UILabel(frame); 
     label.Font = _labelFont; 
     label.Text = caption; 
     AddView(label); 
     _currentTop += 2; 
    } 

    private UITextField AddDateTimeView(out UIDatePicker datePicker) 
    { 
     var textField = AddTextField(); 

     datePicker = new UIDatePicker(); 
     datePicker.Mode = UIDatePickerMode.DateAndTime; 

     textField.InputView = datePicker; 

     return textField; 
    } 

    private UITextField AddTextField() 
    { 
     var frame = new RectangleF(_leftMargin, _currentTop, 300, _pickerHeight); 
     var textField = new UITextField(frame); 
     textField.Layer.BorderColor = UIColor.Black.CGColor; 
     textField.Layer.BorderWidth = 1f; 
     textField.Font = _controlFont; 
     textField.LeftView = _paddingInsert; 
     textField.LeftViewMode = UITextFieldViewMode.Always; 
     AddView(textField); 
     return textField; 
    } 

    private void AddView(UIView view) 
    { 
     View.AddSubview(view); 
     _currentTop += (int)view.Frame.Height; 
    } 
} 

任何想法?

UPDATE

這是工作的自定義代碼:

public class DatePickerDateAndTimeTargetBinding : MvxConvertingTargetBinding 
{ 
    public DatePickerDateAndTimeTargetBinding(object target) : base(target) 
    { 
    } 

    public override Type TargetType 
    { 
     get { return typeof(DateTime); } 
    } 

    protected UIDatePicker DatePicker 
    { 
     get { return (UIDatePicker) Target; } 
    } 

    public override void SubscribeToEvents() 
    { 
     DatePicker.ValueChanged += DatePickerValueChanged; 
    } 

    private void DatePickerValueChanged(object sender, EventArgs e) 
    { 
     var target = Target as UIDatePicker; 

     if (target == null) 
      return; 

     var value = GetDate(target); 
     FireValueChanged(value); 
    } 

    protected override void SetValueImpl(object target, object value) 
    { 
     var datePicker = (UIDatePicker) target; 
     datePicker.Date = (DateTime)value; 
    } 

    private DateTime GetDate(UIDatePicker datePicker) 
    { 
     var dateTime = DateTime.SpecifyKind(datePicker.Date, DateTimeKind.Unspecified); 
     var localDateTime = dateTime.ToLocalTime(); 
     return localDateTime; 
    } 

    public override MvxBindingMode DefaultMode 
    { 
     get { return MvxBindingMode.TwoWay; } 
    } 

    protected override void Dispose(bool isDisposing) 
    { 
     if (isDisposing) 
     { 
      var target = Target as UIDatePicker; 
      if (target != null) 
      { 
       target.ValueChanged -= DatePickerValueChanged; 
      } 
     } 

     base.Dispose(isDisposing); 
    } 

} 

這裏是啓動代碼接線起來:

protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry) 
{ 
    registry.RegisterCustomBindingFactory<UIDatePicker>(
        "DateAndTime", 
        binary => new DatePickerDateAndTimeTargetBinding(binary)); 
    base.FillTargetFactories(registry); 
} 

回答

2
+0

謝謝斯圖爾特。我會放棄它。 –

+0

我寫了一個基於N = 28的自定義DateAndTime聯編程序,並用代碼更新了我的問題。 FireValueChange被調用,但綁定的vm屬性不會被調用。有任何想法嗎? –

+0

沒有想法 - 沒有 - 對不起 – Stuart