【问题标题】:Xamarin custom DatePicker lose bindingXamarin 自定义 DatePicker 失去绑定
【发布时间】:2017-12-13 16:22:34
【问题描述】:

我有这个自定义视图:

public class VolosDatePicker : Button {
    private DatePicker _Picker;
    private IViewContainer<View> _ParentLayout;

    public static readonly BindableProperty DateProperty = BindableProperty.Create(nameof(Date), typeof(DateTime?), typeof(VolosDatePicker));
    public DateTime? Date {
        get { return (DateTime?)GetValue(DateProperty); }
        set { SetValue(DateProperty, value); }
    }

    private string TextFormat = Utente.UteLoggato.formatoData;
    private string DefaultText = "click me";

    //public static readonly BindableProperty DefaultTextProperty = BindableProperty.Create<VolosDatePicker, string>(p => p.DefaultText, "Pick Date...");

    public VolosDatePicker() {
        //create the datepicker, make it invisible on the form.
        _Picker = new DatePicker {
            IsVisible = false
        };

        //handle the focus/unfocus or rather the showing and hiding of the dateipicker
        _Picker.Focused += _Picker_Focused;
        _Picker.Unfocused += _Picker_Unfocused;

        //command for the button
        Command = new Command((obj) => {
            //try to get the parent layout and add the datepicker
            if (_ParentLayout == null) {
                _ParentLayout = _GetParentLayout(Parent);
                if (_ParentLayout != null) {
                    //add the picker to the closest layout up the tree
                    _ParentLayout.Children.Add(_Picker);
                } else {
                    throw new InvalidOperationException("The DatePickerButton needs to be inside an Layout type control that can have other children");
                }
            }
            //show the picker modal
            _Picker.Focus();
        });
        _UpdateText();
    }

    private IViewContainer<View> _GetParentLayout(Element Parent) {
        //StackLayout, RelativeLayout, Grid, and AbsoluteLayout all implement IViewContainer,
        //it would be very rare that this method would return null.
        IViewContainer<View> parent = Parent as IViewContainer<View>;
        if (Parent == null) {
            return null;
        } else if (parent != null) {
            return parent;
        } else {
            return _GetParentLayout(Parent.Parent);
        }
    }

    void _Picker_Focused(object sender, FocusEventArgs e) {
        //default the date to now if Date is empty
        _Picker.Date = Date ?? DateTime.Now;
    }

    void _Picker_Unfocused(object sender, FocusEventArgs e) {
        //this always sets.. can't cancel the dialog.
        Date = _Picker.Date;
        _UpdateText();
    }

    protected override void OnBindingContextChanged() {
        base.OnBindingContextChanged();
        _UpdateText();
    }

    private void _UpdateText() {
        //the button has a default text, use that the first time.
        if (Date != null) {
            //default formatting is in the FormatProperty BindableProperty 
            base.Text = Date.Value.ToString(TextFormat);
        } else {
            base.Text = DefaultText;
        }
    }

    protected override void OnPropertyChanging(string propertyName = null) {
        //set this so there is an old date for the DateChangedEventArgs
        base.OnPropertyChanging(propertyName);
        if (propertyName == DateProperty.PropertyName) {
            //_OldDate = Date;
            _UpdateText();
            //if (_OldDate != null && Date != null) DateSelected(this, new DateChangedEventArgs((DateTime)_OldDate, (DateTime)Date));
        }
    }

    protected override void OnPropertyChanged(string propertyName = null) {
        base.OnPropertyChanged(propertyName);
        if (propertyName == DateProperty.PropertyName) {              
            _UpdateText();
        }
    }
}

在我的 XAML 页面中,我有这个绑定:

<view:VolosDatePicker Date="{Binding WoSpesaDett.DataSpesa}" Grid.Row="0" Grid.Column="1" />

我是这样设置这个日期的:

WoSpesaDett.DataSpesa = new System.DateTime(2015, 5, 18);
RaisePropertyChanged(() => WoSpesaDett);

在我使用此方法之前,DatePicker 的日期值设置正确,但在我尝试使用控件选择器设置日期后,上述方法停止工作。

如果我从控件选择器中选择任何日期,然后尝试使用上述方法以编程方式设置日期,则日期不会更改。

它似乎失去了与属性WoSpesaDett.DataSpesa的绑定。

【问题讨论】:

    标签: c# android ios xamarin datepicker


    【解决方案1】:

    根据documentation

    可选地,在创建 BindableProperty 实例时,可以指定以下参数:

    绑定模式。这用于指定方向 属性值更改将传播。在默认绑定模式下, 更改将从源传播到目标。

    尝试将绑定模式设置为TwoWay,如下所示:

    <view:VolosDatePicker Date="{Binding WoSpesaDett.DataSpesa, Mode=TwoWay}" Grid.Row="0" Grid.Column="1" />
    

    或编辑BindableProperty 本身。

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 2018-12-16
      • 2016-01-18
      • 1970-01-01
      • 2019-02-17
      • 1970-01-01
      • 2019-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多