Xamarin.forms 在xamarin.Fomrs中的可为空的日期选择器自定义控件中选择当前日期时,不会触发SelectedDate事件
我已经实现了可空日期选择器来显示占位符to date字段以及其中的空日期,您可以看到下面的代码 现在的问题是,当我单击当前日期时,DateSelected事件不会触发,当您选择上一个日期或下一个日期但未选择当前日期时,它会触发Xamarin.forms 在xamarin.Fomrs中的可为空的日期选择器自定义控件中选择当前日期时,不会触发SelectedDate事件,xamarin.forms,xamarin.android,xamarin.ios,Xamarin.forms,Xamarin.android,Xamarin.ios,我已经实现了可空日期选择器来显示占位符to date字段以及其中的空日期,您可以看到下面的代码 现在的问题是,当我单击当前日期时,DateSelected事件不会触发,当您选择上一个日期或下一个日期但未选择当前日期时,它会触发 _dialog.SetButton(Constant.DONE, (sender, e) => { SetDate(_dialog.DatePicker.DateTime); Element.Format = Element
_dialog.SetButton(Constant.DONE, (sender, e) =>
{
SetDate(_dialog.DatePicker.DateTime);
Element.Format = Element._originalFormat;
Element.AssignValue();
if (_dialog.DatePicker.DateTime == DateTime.Today)
{
MessagingCenter.Send<Object,DateTime>(this, "SameDate", view.Date);
}
});
提前谢谢
数据控制
public class NDatePicker : DatePicker
{
public NDatePicker()
{
Format = "MM'/'dd'/'yyyy";
}
public string _originalFormat = null;
public static readonly BindableProperty PlaceHolderProperty =
BindableProperty.Create(nameof(PlaceHolder), typeof(string), typeof(c), "'MM/DD/YYYY'");
public string PlaceHolder
{
get { return (string)GetValue(PlaceHolderProperty); }
set { SetValue(PlaceHolderProperty, value); }
}
public static readonly BindableProperty NullableDateProperty =
BindableProperty.Create(nameof(NullableDate), typeof(DateTime?), typeof(NDatePicker), null, defaultBindingMode: BindingMode.TwoWay);
public DateTime? NullableDate
{
get { return (DateTime?)GetValue(NullableDateProperty); }
set
{
SetValue(NullableDateProperty, value);
UpdateDate();
}
}
private void UpdateDate()
{
if (NullableDate != null)
{
if (_originalFormat != null)
{
Format = _originalFormat;
}
}
else
{
Format = PlaceHolder;
}
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
if (BindingContext != null)
{
_originalFormat = Format;
UpdateDate();
}
}
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == DateProperty.PropertyName || (propertyName == IsFocusedProperty.PropertyName
&& !IsFocused && (Date.ToString(Constant.DATE_FORMAT) == DateTime.Now.ToString(Constant.DATE_FORMAT))))
{
AssignValue();
}
if (propertyName == NullableDateProperty.PropertyName && NullableDate.HasValue)
{
Date = NullableDate.Value;
if (Date.ToString(_originalFormat) == DateTime.Now.ToString(_originalFormat))
{
//this code was done because when date selected is the actual date the"DateProperty" does not raise
UpdateDate();
}
}
}
public void AssignValue()
{
NullableDate = Date;
UpdateDate();
}
}
C.C
public class NDatePickerDroid : ViewRenderer<NDatePicker, EditText>
{
DatePickerDialog _dialog;
public NDatePickerDroid(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<NDatePicker> e)
{
base.OnElementChanged(e);
SetNativeControl(new EditText(Context));
if (Control == null || e.NewElement == null)
return;
Control.TextSize = 14;
Control.Click += OnPickerClick;
Control.Text = Element.Date.ToString(Element.Format);
Control.KeyListener = null;
Control.FocusChange += OnPickerFocusChange;
Control.Enabled = Element.IsEnabled;
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Xamarin.Forms.DatePicker.DateProperty.PropertyName || e.PropertyName == Xamarin.Forms.DatePicker.FormatProperty.PropertyName)
SetDate(Element.Date);
}
void OnPickerFocusChange(object sender, Android.Views.View.FocusChangeEventArgs e)
{
if (e.HasFocus)
{
ShowDatePicker();
}
}
protected override void Dispose(bool disposing)
{
if (Control != null)
{
Control.Click -= OnPickerClick;
Control.FocusChange -= OnPickerFocusChange;
if (_dialog != null)
{
_dialog.Hide();
_dialog.Dispose();
_dialog = null;
}
}
base.Dispose(disposing);
}
void OnPickerClick(object sender, EventArgs e)
{
ShowDatePicker();
}
void SetDate(DateTime date)
{
Control.Text = date.ToString(Element.Format);
Element.Date = date;
}
private void ShowDatePicker()
{
CreateDatePickerDialog(Element.Date.Year, Element.Date.Month - 1, Element.Date.Day);
_dialog.Show();
}
void CreateDatePickerDialog(int year, int month, int day)
{
NDatePicker view = Element;
_dialog = new DatePickerDialog(Context, (o, e) =>
{
view.Date = e.Date;
((IElementController)view).SetValueFromRenderer(VisualElement.IsFocusedProperty, false);
Control.ClearFocus();
_dialog = null;
}, year, month, day);
_dialog.SetButton(Constant.DONE, (sender, e) =>
{
SetDate(_dialog.DatePicker.DateTime);
Element.Format = Element._originalFormat;
Element.AssignValue();
});
}
}
public类droid:ViewRenderer
{
DatePickerDialog对话框;
公共Kerdroid(上下文):基础(上下文)
{
}
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
SetNativeControl(新编辑文本(上下文));
if(Control==null | | e.NewElement==null)
返回;
Control.TextSize=14;
控件。单击+=OnPickerClick;
Control.Text=Element.Date.ToString(Element.Format);
Control.KeyListener=null;
Control.FocusChange+=OnPickerFocusChange;
Control.Enabled=Element.IsEnabled;
}
受保护的覆盖无效OnElementPropertyChanged(对象发送方,PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(发送方,e);
如果(e.PropertyName==Xamarin.Forms.DatePicker.DateProperty.PropertyName | | e.PropertyName==Xamarin.Forms.DatePicker.FormatProperty.PropertyName)
设置日期(元素日期);
}
void OnPickerFocusChange(对象发送方,Android.Views.View.FocusChangeEventArgs e)
{
如果(例如HasFocus)
{
ShowDatePicker();
}
}
受保护的覆盖无效处置(布尔处置)
{
if(控件!=null)
{
控件。单击-=OnPickerClick;
Control.FocusChange-=OnPickerFocusChange;
如果(_dialog!=null)
{
_dialog.Hide();
_dialog.Dispose();
_dialog=null;
}
}
基地。处置(处置);
}
void OnPickerClick(对象发送方,事件参数e)
{
ShowDatePicker();
}
无效设置日期(日期时间日期)
{
Control.Text=date.ToString(Element.Format);
元素。日期=日期;
}
私有void ShowDatePicker()
{
CreateDatePickerDialog(Element.Date.Year,Element.Date.Month-1,Element.Date.Day);
_dialog.Show();
}
void CreateDatePickerDialog(整数年、整数月、整数天)
{
视图=元素;
_dialog=newdatepickerdialog(上下文,(o,e)=>
{
view.Date=e.Date;
((IElementController)视图).SetValueFromRenderer(VisualElement.IsFocusedProperty,false);
控件ClearFocus();
_dialog=null;
}年、月、日);
_对话框.SetButton(Constant.DONE,(sender,e)=>
{
SetDate(_dialog.DatePicker.DateTime);
Element.Format=Element.\u原始格式;
元素。赋值();
});
}
}
凯里奥斯酒店
public class NDatePickeriOS : DatePickerRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
{
base.OnElementChanged(e);
if (e.NewElement != null && Control != null)
{
AddClearButton();
Control.Font = Control.Font.WithSize(14);
Control.BorderStyle = UITextBorderStyle.Line;
Control.Layer.BorderColor = UIColor.LightGray.CGColor;
Control.Layer.BorderWidth = 1;
if (Device.Idiom == TargetIdiom.Tablet)
{
Control.Font = UIFont.SystemFontOfSize(25);
}
}
}
private void AddClearButton()
{
UIToolbar originalToolbar = Control.InputAccessoryView as UIToolbar;
if (originalToolbar != null && originalToolbar.Items.Length <= 2)
{
var clearButton = new UIBarButtonItem(Constant.CLEAR, UIBarButtonItemStyle.Plain, ((sender, ev) =>
{
NDatePicker baseDatePicker = Element as NDatePicker;
Element.Unfocus();
Element.Date = DateTime.Now;
//baseDatePicker.CleanDate();
}));
var newItems = new List<UIBarButtonItem>();
foreach (var item in originalToolbar.Items)
{
newItems.Add(item);
}
newItems.Insert(0, clearButton);
originalToolbar.Items = newItems.ToArray();
originalToolbar.SetNeedsDisplay();
}
}
}
公共类:DatePickerRenderer
{
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
if(例如NewElement!=null&&Control!=null)
{
AddClearButton();
Control.Font=Control.Font.WithSize(14);
Control.BorderStyle=UITextBorderStyle.Line;
Control.Layer.BorderColor=UIColor.LightGray.CGColor;
Control.Layer.BorderWidth=1;
if(Device.Idiom==TargetIdiom.Tablet)
{
Control.Font=UIFont.SystemFontOfSize(25);
}
}
}
私有void AddClearButton()
{
UIToolbar originalToolbar=控件。InputAccessoryView作为UIToolbar;
if(originalToolbar!=null&&originalToolbar.Items.Length
{
ndadepicker baseDatePicker=作为ndadepicker的元素;
元素。Unfocus();
Element.Date=DateTime.Now;
//baseDatePicker.CleanDate();
}));
var newItems=新列表();
foreach(originalToolbar.Items中的变量项)
{
新增项目。添加(项目);
}
newItems.Insert(0,clearButton);
originalToolbar.Items=newItems.ToArray();
originalToolbar.SetNeedsDisplay();
}
}
}
XAML是
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" Margin="0,2" HeightRequest="60">
<control:NDatePicker NullableDate="{Binding DateAnswer}" DateSelected="DateChanged" HorizontalOptions="FillAndExpand" VerticalOptions="Center"/>
</StackLayout>
选择当前日期时,您可以使用此选项向页面发送消息
_dialog.SetButton(Constant.DONE, (sender, e) =>
{
SetDate(_dialog.DatePicker.DateTime);
Element.Format = Element._originalFormat;
Element.AssignValue();
if (_dialog.DatePicker.DateTime == DateTime.Today)
{
MessagingCenter.Send<Object,DateTime>(this, "SameDate", view.Date);
}
});
\u dialog.SetButton(Constant.DONE,(sender,e)=>
{
SetDate(_dialog.DatePicker.DateTime);
Element.Format=Element.\u原始格式;
元素。赋值();
如果(_dialog.DatePicker.DateTime==DateTime.Today)
{
MessagingCenter.Send(这是“SameDate”,view.Date);
}
});
在您的page.xaml.cs中:
public YourPage()
{
InitializeComponent();
MessagingCenter.Subscribe<Object,DateTime>(this, "SameDate", (sender,args) =>
{
DateTime dateTime = args; //triggered here
});
}
public YourPage()
{
初始化组件();
MessagingCenter.Subscribe(此“SameDate”,(发件人,参数)=>
{
DateTime DateTime=args;//在此处触发
});
}
你能显示你的xaml代码吗?@LeoZhu MSFT更新了问题,请检查DatePick的默认日期是DateTime.Today。因此我认为如果你选择当前日期,它不会触发datechange事件。是的,我理解这一点,这就是为什么日期更改事件不是triggered@LeoZhu-MSFT是否有其他方式在所选日期触发此事件(确定按钮)我会检查此项并让您知道,谢谢advance@KK它能工作吗?