Xamarin.forms 在xamarin.Fomrs中的可为空的日期选择器自定义控件中选择当前日期时,不会触发SelectedDate事件

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

我已经实现了可空日期选择器来显示占位符to date字段以及其中的空日期,您可以看到下面的代码

现在的问题是,当我单击当前日期时,DateSelected事件不会触发,当您选择上一个日期或下一个日期但未选择当前日期时,它会触发

 _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它能工作吗?