我有这个自定义视图:
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
的绑定。
答案 0 :(得分:1)
可选地,在创建BindableProperty实例时,可以指定以下参数:
绑定模式。这用于指定方向 财产价值变化将传播。在默认绑定模式下, 更改将从源传播到目标。
尝试将绑定模式设置为TwoWay
,如下所示:
<view:VolosDatePicker Date="{Binding WoSpesaDett.DataSpesa, Mode=TwoWay}" Grid.Row="0" Grid.Column="1" />
或编辑BindableProperty
本身。
希望它有所帮助!