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

Clicking the current 'SelectedDate' on the calendar returns null. #18

Closed
Agistaris opened this issue Jan 15, 2024 · 3 comments · Fixed by #109
Closed

Clicking the current 'SelectedDate' on the calendar returns null. #18

Agistaris opened this issue Jan 15, 2024 · 3 comments · Fixed by #109

Comments

@Agistaris
Copy link

Agistaris commented Jan 15, 2024

To replicate, simply click the same date twice on the calendar and it will return 'null'. I believe the behavior should be to return the date regardless of it being the current 'SelectedDate'. Just trying to report as much as I can. This is the best Calendar I have found thus far. Whatever I can do to help, let me know!

I'm using this work around for now for my purposes (simplified my code for this example) to maintain the Selected Date Background color:

private DateTime? _calendarDate = DateTime.Now.Date;
public DateTime? CalendarDate
{
    get => _calendarDate;
    set
    {
        _calendarDate = value;
        OnPropertyChanged(nameof(CalendarDate));
        SelectedMonth = CalendarDate?.ToString("MMMM, yyyy");
    }
}

private string _selectedMonth = "";
public string SelectedMonth
{
    get => _selectedMonth;
    set
    {
        _selectedMonth = value;
        OnPropertyChanged(nameof(SelectedMonth));
    }
}

private void CalendarDayTapped()
{
    var tempSelectedDate = Cal.SelectedDate;

    if (tempSelectedDate == null)
    {
        Cal.SelectedDate = CalendarDate;
    }
    else
    {
        CalendarDate = tempSelectedDate;
    }

    HideCalendar(null, null);

}
@yurkinh
Copy link
Owner

yurkinh commented Jan 15, 2024

Hi @Agistaris
Thanks for reporting another issue and for kind words)
I think you will like the new version even more)
Yes - this behaviour is programmed so far.
One click - you select data Command (DateTime selectedDate)
Second click - you deselect data ( Command (null))
We have two-way binding and this is a way to deselect the selected date.
Any idea how can I improve it without breaking changes?

@Agistaris
Copy link
Author

Agistaris commented Jan 16, 2024

@yurkinh I was looking at the binding, is there a chance something like this might work? I also took a small wack at the 'BindableProperty' as well. Let me know your thoughts or if this conflicts with anything you can foresee? In my mind the null behavior is exactly what you want for the 'multi-selection' or 'range' variations of the calendar. However for the simple calendar, it may be more useful to retain the current date when clicking the current 'SelectedDate' more than once.

/// <summary>
/// Bindable property for SelectedDate
/// </summary>
public static readonly BindableProperty SelectedDateProperty =
  BindableProperty.Create(nameof(SelectedDate), typeof(DateTime?), typeof(Calendar), null, BindingMode.TwoWay, propertyChanged: OnSelectedDateChanged);

private static void OnSelectedDateChanged(BindableObject bindable, object oldValue, object newValue)
{
    var control = (Calendar)bindable;
    var newDate = (DateTime?)newValue;
    
    // Only update if the new date is different from the current date
    if (control.SelectedDate != newDate)
    {
        control.SelectedDate = newDate;
    
        if (!control._isSelectingDates || control.monthDaysView.CurrentSelectionEngine is SingleSelectionEngine)
        {
            control.SetValue(SelectedDatesProperty, newDate.HasValue ? new List<DateTime> { newDate.Value } : new List<DateTime>());
        }
        else
        {
            control._isSelectingDates = false;
        }
    }
}

public DateTime? SelectedDate
{
    get => (DateTime?)GetValue(SelectedDateProperty);
    set
    {
        // If the new value is null, use the current value of SelectedDate
        DateTime? newValue = value ?? SelectedDate;
        SetValue(SelectedDateProperty, newValue);
        
        // Keep original method for 'SelectedDatesProperty'
        SetValue(SelectedDatesProperty, value.HasValue ? new List<DateTime> { value.Value } : null);
    }
}

Perhaps it can be set as a 'bool' like 'RetainSelectedDate'.

public DateTime? SelectedDate
{
    get => (DateTime?)GetValue(SelectedDateProperty);
    set
    {
        // If the new value is null, use the current value of SelectedDate
        if (RetainSelectedDate) 
        {
            DateTime? newValue = value ?? SelectedDate;
            SetValue(SelectedDateProperty, newValue);
        } 
        else
        {
            SetValue(SelectedDateProperty, value);
        }
        
        // Keep original method for 'SelectedDatesProperty'
        SetValue(SelectedDatesProperty, value.HasValue ? new List<DateTime> { value.Value } : null);
    }
}

@yurkinh
Copy link
Owner

yurkinh commented Jan 16, 2024

@Agistaris Yes, we can do this but it is better to implement this property for all types of calendars otherwise we will get inconsistency

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

Successfully merging a pull request may close this issue.

2 participants