Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DatePicker doesnt fire for DateSelected event on same date #13156

Open
duindain opened this issue Feb 7, 2023 · 10 comments · May be fixed by #16153
Open

DatePicker doesnt fire for DateSelected event on same date #13156

duindain opened this issue Feb 7, 2023 · 10 comments · May be fixed by #16153

Comments

@duindain
Copy link

duindain commented Feb 7, 2023

Description

The DatePicker has a default date of todays date, if someone selects that same date the dialog closes but the DateSelected doesn't fire

If you didn't pass in an initial date this effectively prevents a user from selecting today's date, if you do have a date bound it prevents selecting that date which means any extra code in the DateSelected event doesn't fire

This is related to #9180 though that was Android specific and for .Net 6

Steps to Reproduce

  1. Create File > New .Net Maui App
  2. Add a DatePicker to MainPage.xaml
  3. Add a DateSelected event handler
  4. Add a debug statement to the handler to see when the event is fired
  5. Run the app and select todays date, no event is fired

Link to public reproduction project repository

https://github.com/duindain/DateChanger

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

iOS, Android, Windows, I was not able test on other platforms

Affected platform versions

Android 11 and up, WindowsSDK 10.0.19041, iOS 16.1

Did you find any workaround?

No response

Relevant log output

No response

@duindain duindain added the t/bug Something isn't working label Feb 7, 2023
@jsuarezruiz jsuarezruiz added the area-controls-datetimepicker DatePicker, TimePicker label Feb 7, 2023
@ghost ghost added the legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor label Feb 7, 2023
@mattleibow mattleibow added t/enhancement ☀️ New feature or request and removed t/bug Something isn't working labels Feb 7, 2023
@mattleibow mattleibow added this to the Backlog milestone Feb 7, 2023
@ghost
Copy link

ghost commented Feb 7, 2023

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@mattleibow
Copy link
Member

Maybe this issue is more we need a "null date" option so that there is a change. Or maybe we need a DateChanged and PickerClosed event?

I see this PR does something: https://github.com/dotnet/maui/pull/9727/files?w=1

However it changes the property type and I think that is a bit breaking. We could use things like DateTime.MinDate instead...

@duindain
Copy link
Author

duindain commented Feb 7, 2023

A nullable date would be ideal, i actually discovered this while creating my own nullable datepicker

The event is DateSelected not DateChanged it should trigger on any date selected not just changes

@hariywill

This comment was marked as off-topic.

@PureWeen
Copy link
Member

PureWeen commented Dec 18, 2023

Archive.zip

Here's a workaround that should work on ios/android/winui

Basically the date is always passed back up into the xplat layer but the BP doesn't fire a property changed so you just need to intercept via the interface.

I'm not really sure how to make this work on catalyst though. On catalyst the event only fires when the value is changed and I couldn't figure out a way to detect when the dialog is opened and then closed. I think on catalyst you might have to get clever with it, like, have two controls on the screen and the non visible one opens the dialog.

Unless someone knows of a way to make it work?

AFAIK

In Mac Catalyst, there isn't a direct way to know if the UIDatePicker dialog has been opened or closed because UIDatePicker does not provide events for these actions. However, you can use the ValueChanged event to know when a user has interacted with the UIDatePicker.

ValueChanged doesn't fire though when the Value hasn't changed.

using Microsoft.Maui.Controls;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;

namespace DateChanger
{
    public class CustomDatePicker : DatePicker, IDatePicker
    {
        public CustomDatePicker()
        {
        }

        protected override void OnHandlerChanging(HandlerChangingEventArgs args)
        {
            base.OnHandlerChanging(args);


#if WINDOWS
            if (args.OldHandler is IDatePickerHandler dph)
            {
                dph.PlatformView.Closed -= PlatformView_Closed;
            }
#endif
            

        }

        protected override void OnHandlerChanged()
        {
            base.OnHandlerChanged();

            if (Handler is IDatePickerHandler dphNew)
            {
#if WINDOWS
                dphNew.PlatformView.Closed += PlatformView_Closed;
#endif
            }
        }

#if WINDOWS
        private void PlatformView_Closed(object sender, object e)
        {
            OnPropertyChanged(nameof(Date));
        }
#endif


        DateTime IDatePicker.Date 
        { 
            get => Date;
            set
            {
                Date = value;
                OnPropertyChanged(nameof(Date));
            }
        }
    }
}

@its-AliRaza
Copy link

its-AliRaza commented Feb 7, 2024

Here's a workaround that should work.


 public class FormDatePicker : Microsoft.Maui.Controls.DatePicker, IDatePicker
 {
     DateTime IDatePicker.Date
     {
         get => Date;
         set
         {
             if (value.Equals(DateTime.Today.Date))
                 Date = value.AddDays(-1);
             Date = value;
             OnPropertyChanged(nameof(Date));
         }
     }
 }

@Eilon Eilon removed the legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor label May 10, 2024
@corne-ac
Copy link

This is still an issue, and the same for the TimePicker. its been over a year and still no fix. Used the Workaround suggested by @its-AliRaza .

@StepKie
Copy link

StepKie commented Oct 10, 2024

@PureWeen @Eilon @samhouts

Sorry for being so insistent on this.
I guess I don't fully understand why this was removed from Under Consideration and added to Backlog after being open for over one and a half years, especially when there is even a merge request #16153 ready to address this issue (at least for DatePicker, something analogous has to be added for TimePicker, which does not even have a TimeSelected event)

The "workaround" shared here also does not cover all scenarios (e.g. when Date/TimePicker has previously been set to a different date than the default DateTime.Today.Date).

It would also suffice to have a way to distinguish whether the user closed the Picker with "Cancel" or "Ok", but there is currently no method or event for differentiating between the scenario Cancel and Ok after selecting the same date as before.

This issue is of high importance to a significant number of users, as can be deduced from the large amount of interaction and duplicates that are being created.

Thank you again for your consideration.

@StepKie
Copy link

StepKie commented Oct 10, 2024

Here's a workaround that should work.


 public class FormDatePicker : Microsoft.Maui.Controls.DatePicker, IDatePicker
 {
     DateTime IDatePicker.Date
     {
         get => Date;
         set
         {
             if (value.Equals(DateTime.Today.Date))
                 Date = value.AddDays(-1);
             Date = value;
             OnPropertyChanged(nameof(Date));
         }
     }
 }

I suggest replacing value.Equals(DateTime.Today.Date) with value.Equals(Date). This way it also works after the value was changed inside the picker once.

Edit: analogous workaround for TimePicker (if anyone needs it):

public class TimePickerWrapped : TimePicker, ITimePicker
{
    TimeSpan ITimePicker.Time
    {
        get => Time;
        set
        {
            if (value == Time)
            {
                Time += TimeSpan.FromSeconds(1);
            }

            Time = value;
            OnPropertyChanged(nameof(Time));
        }
    }
}

@NiranjanShirke22
Copy link

@StepKie thanks alot , you saved my time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet