Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion maui/src/Picker/PickerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ internal void InvokeCancelButtonClickedEvent(object sender, EventArgs eventArgs)
/// <returns>Returns the internal selection or not</returns>
internal bool IsScrollSelectionAllowed()
{
if (Mode != PickerMode.Default && FooterView.Height != 0 && FooterView.ShowOkButton)
if (Mode != PickerMode.Default && (int)FooterView.Height != 0 && FooterView.ShowOkButton && FooterTemplate == null)
{
return true;
}
Expand Down
30 changes: 17 additions & 13 deletions maui/src/Picker/SfDatePicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,22 @@ void InitializePickerStyle()
SetDynamicResource(DisabledTextColorProperty, "SfDatePickerDisabledTextColor");
}

/// <summary>
/// Method to update Selected Date based on confirmation.
/// </summary>
/// <param name="shouldUpdateSelection">Denotes whether selected value needs to be updated</param>
void UpdateInternalValueToSelection(bool shouldUpdateSelection)
{
// If the picker is not in Default mode and an internal selected date exists
if (shouldUpdateSelection && _internalSelectedDate != null && !DatePickerHelper.IsSameDate(_internalSelectedDate, SelectedDate))
{
// Update the selected date with the internal selected date
SelectedDate = _internalSelectedDate.Value;
// Clear the internal selected date after applying it
_internalSelectedDate = null;
}
}

#endregion

#region Override Methods
Expand Down Expand Up @@ -1533,19 +1549,7 @@ protected override void OnPopupOpened(EventArgs e)
/// <param name="e">The event arguments</param>
protected override void OnOkButtonClicked(EventArgs e)
{
// If the picker is not in Default mode and an internal selected date exists
if (IsScrollSelectionAllowed() && _internalSelectedDate != null)
{
// If the internal selected date is different from the currently selected date
if (!DatePickerHelper.IsSameDate(_internalSelectedDate, SelectedDate))
{
// Update the selected date with the internal selected date
SelectedDate = _internalSelectedDate.Value;
// Clear the internal selected date after applying it
_internalSelectedDate = null;
}
}

UpdateInternalValueToSelection(IsScrollSelectionAllowed());
InvokeOkButtonClickedEvent(this, e);
if (AcceptCommand != null && AcceptCommand.CanExecute(e))
{
Expand Down
60 changes: 46 additions & 14 deletions maui/src/Picker/SfDateTimePicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1888,6 +1888,7 @@ void GenerateDatePickerColumns()
List<int> formatStringOrder = DatePickerHelper.GetFormatStringOrder(out dayFormat, out monthFormat, DateFormat);
DateTime maxDate = DatePickerHelper.GetValidMaxDate(MinimumDate, MaximumDate);
DateTime date = SelectedDate ?? _previousSelectedDateTime;
date = GetScrollSelectedDateTime(date);
DateTime selectedDate = DatePickerHelper.GetValidDateTime(date, MinimumDate, maxDate);
ObservableCollection<PickerColumn> pickerColumns = new ObservableCollection<PickerColumn>();
foreach (int index in formatStringOrder)
Expand Down Expand Up @@ -2034,6 +2035,7 @@ void GenerateTimePickerColumns()
List<int> formatStringOrder = TimePickerHelper.GetFormatStringOrder(out hourFormat, TimeFormat);
DateTime maxDate = DatePickerHelper.GetValidMaxDate(MinimumDate, MaximumDate);
DateTime date = SelectedDate ?? _previousSelectedDateTime;
date = GetScrollSelectedDateTime(date);
DateTime selectedDate = DatePickerHelper.GetValidDateTime(date, MinimumDate, maxDate);
TimeSpan selectedTime = new TimeSpan(0, selectedDate.Hour, selectedDate.Minute, selectedDate.Second, selectedDate.Millisecond);
ObservableCollection<PickerColumn> pickerColumns = new ObservableCollection<PickerColumn>();
Expand Down Expand Up @@ -2157,7 +2159,7 @@ PickerColumn GenerateMinuteColumn(TimeSpan? selectedTime, DateTime? selectedDate
DateTime? minimumDate = null;
DateTime? maximumDate = null;
DateTime maxDate = DatePickerHelper.GetValidMaxDate(MinimumDate, MaximumDate);
DateTime? date = SelectedDate ?? _previousSelectedDateTime;
DateTime? date = selectedDate ?? _previousSelectedDateTime;
if (date.Value.Date <= MinimumDate.Date)
{
minimumDate = MinimumDate;
Expand Down Expand Up @@ -2320,6 +2322,35 @@ void IntializePickerStyle()
SetDynamicResource(DisabledTextColorProperty, "SfDateTimePickerDisabledTextColor");
}

/// <summary>
/// Method to update Selected Date and Time based on confirmation.
/// </summary>
/// <param name="shouldUpdateSelection">Denotes whether selected value needs to be updated</param>
void UpdateInternalValueToSelection(bool shouldUpdateSelection)
{
// If the picker is not in Default mode and an internal selected date-time exists
if (shouldUpdateSelection && _internalSelectedDateTime != null && !DatePickerHelper.IsSameDateTime(_internalSelectedDateTime, SelectedDate))
{
// Update the selected date with the internal selected date-time
SelectedDate = _internalSelectedDateTime.Value;
// Clear the internal selected date-time after applying it
_internalSelectedDateTime = null;
}
}

/// <summary>
/// Gets the internally selected date and time when scroll selection is allowed.
/// </summary>
/// <returns>
/// The <see cref="DateTime"/> value if scroll selection is enabled and an internal selection exists; otherwise, the provided <paramref name="dateTime"/> parameter.
/// </returns>
DateTime GetScrollSelectedDateTime(DateTime dateTime)
{
return IsScrollSelectionAllowed() && _internalSelectedDateTime.HasValue
? _internalSelectedDateTime.Value
: dateTime;
}

#endregion

#region Override Methods
Expand Down Expand Up @@ -2498,6 +2529,19 @@ protected override void OnPickerLoading()
/// <param name="e">The event arguments.</param>
protected override void OnPopupClosed(EventArgs e)
{
if (_internalSelectedDateTime != null)
{
_internalSelectedDateTime = null;
if (_selectedIndex == 0)
{
BaseHeaderView.DateText = GetDateHeaderText();
}
else
{
BaseHeaderView.TimeText = this.GetTimeHeaderText();
}
}

InvokeClosedEvent(this, e);
}

Expand Down Expand Up @@ -2525,19 +2569,7 @@ protected override void OnPopupOpened(EventArgs e)
/// <param name="e">The event arguments.</param>
protected override void OnOkButtonClicked(EventArgs e)
{
// If the picker is not in Default mode and an internal selected date-time exists
if (IsScrollSelectionAllowed() && _internalSelectedDateTime != null)
{
// If the internal selected date-time is different from the currently selected date
if (!DatePickerHelper.IsSameDateTime(_internalSelectedDateTime, SelectedDate))
{
// Update the selected date with the internal selected date-time
SelectedDate = _internalSelectedDateTime.Value;
// Clear the internal selected date-time after applying it
_internalSelectedDateTime = null;
}
}

UpdateInternalValueToSelection(IsScrollSelectionAllowed());
InvokeOkButtonClickedEvent(this, e);
if (AcceptCommand != null && AcceptCommand.CanExecute(e))
{
Expand Down
58 changes: 31 additions & 27 deletions maui/src/Picker/SfPicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,36 @@ void InitializePickerStyle()
SetDynamicResource(NormalFontSizeProperty, "SfPickerNormalFontSize");
}

/// <summary>
/// Method to update Selected Index based on confirmation.
/// </summary>
/// <param name="shouldUpdateSelection">Denotes whether selected value needs to be updated</param>
void UpdateInternalValueToSelection(bool shouldUpdateSelection)
{
// If the picker is not in Default mode and has a single column
if (shouldUpdateSelection && BaseColumns.Count == 1)
{
// Iterate through each column in the picker
foreach (PickerColumn column in this.Columns)
{
// Skip columns that have no internal selection
if (column._internalSelectedIndex == -1)
{
continue;
}
// If the column has a valid item source and it's a list
if (column.ItemsSource != null && column.ItemsSource is IList pickerCollection && column.SelectedIndex >= 0 && column.SelectedIndex < pickerCollection.Count)
{
// Apply the internal selected index to the actual selected index
int selectedIndex = column._internalSelectedIndex;
column._internalSelectedIndex = -1;
// Apply selection
column.SelectedIndex = selectedIndex;
}
}
}
}

#endregion

#region Override Methods
Expand Down Expand Up @@ -759,33 +789,7 @@ protected override void OnPopupOpened(EventArgs e)
/// <param name="e">The event arguments.</param>
protected override void OnOkButtonClicked(EventArgs e)
{
// If the picker is not in Default mode
if (IsScrollSelectionAllowed() && BaseColumns.Count == 1)
{
// Iterate through each column in the picker
foreach (PickerColumn column in this.Columns)
{
// Skip columns that have no internal selection
if (column._internalSelectedIndex == -1)
{
continue;
}
// If the column has a valid item source and it's a list
if (column.ItemsSource != null && column.ItemsSource is IList pickerCollection)
{
// Check if the selected index is within the valid range of the collection
if (column.SelectedIndex >= 0 && column.SelectedIndex < pickerCollection.Count)
{
// Apply the internal selected index to the actual selected index
int selectedIndex = column._internalSelectedIndex;
column._internalSelectedIndex = -1;
// Apply selection
column.SelectedIndex = selectedIndex;
}
}
}
}

UpdateInternalValueToSelection(IsScrollSelectionAllowed());
InvokeOkButtonClickedEvent(this, e);
if (AcceptCommand != null && AcceptCommand.CanExecute(e))
{
Expand Down
30 changes: 17 additions & 13 deletions maui/src/Picker/SfTimePicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1533,6 +1533,22 @@ void InitializePickerStyle()
SetDynamicResource(DisabledTextColorProperty, "SfTimePickerDisabledTextColor");
}

/// <summary>
/// Method to update Selected Time based on confirmation.
/// </summary>
/// <param name="shouldUpdateSelection">Denotes whether selected value needs to be updated</param>
void UpdateInternalValueToSelection(bool shouldUpdateSelection)
{
// If the picker is not in Default mode and an internal selected time exists
if (shouldUpdateSelection && _internalSelectedTime != null && !TimePickerHelper.IsSameTimeSpan(_internalSelectedTime, SelectedTime))
{
// Update the selected time with the internal selected time
this.SelectedTime = _internalSelectedTime.Value;
// Clear the internal selected time after applying it
_internalSelectedTime = null;
}
}

#endregion

#region Override Methods
Expand Down Expand Up @@ -1655,19 +1671,7 @@ protected override void OnPopupOpened(EventArgs e)
/// <param name="e">The event arguments</param>
protected override void OnOkButtonClicked(EventArgs e)
{
// If the picker is not in Default mode and an internal selected time exists
if (IsScrollSelectionAllowed() && _internalSelectedTime != null)
{
// If the internal selected time is different from the currently selected time
if (!TimePickerHelper.IsSameTimeSpan(_internalSelectedTime, SelectedTime))
{
// Update the selected time with the internal selected time
this.SelectedTime = _internalSelectedTime.Value;
// Clear the internal selected time after applying it
_internalSelectedTime = null;
}
}

UpdateInternalValueToSelection(IsScrollSelectionAllowed());
InvokeOkButtonClickedEvent(this, e);
if (AcceptCommand != null && AcceptCommand.CanExecute(e))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3185,6 +3185,79 @@ public void DialogMode_DateBoundaryValues_ValidatesCorrectBehavior()
Assert.True(selectionChangedFired, "SelectionChanged should fire for valid boundary values");
}

[Fact]
public void IsScrollSelectionAllowed_ReturnsFalse_WhenFooterTemplateIsSet_EvenIfOtherConditionsPass()
{
// Arrange: All other conditions met
var picker = new SfDatePicker
{
Mode = PickerMode.Dialog,
FooterTemplate = new DataTemplate(() =>
{
return new Label { Text = "Footer Content" };
})
};
picker.FooterView.Height = 24; // non-zero
picker.FooterView.ShowOkButton = true; // true

// Act
var allowed = picker.IsScrollSelectionAllowed();

// Assert
Assert.False(allowed, "Scroll selection must be disallowed when a custom FooterTemplate is set.");
}

[Fact]
public void IsScrollSelectionAllowed_ReturnsTrue_WhenAllConditionsMet_AndFooterTemplateIsNull()
{
// Arrange: All conditions met and FooterTemplate is null
var picker = new SfDatePicker
{
Mode = PickerMode.Dialog,
};
picker.FooterView.Height = 24;
picker.FooterView.ShowOkButton = true;

// Act
var allowed = picker.IsScrollSelectionAllowed();

// Assert
Assert.True(allowed, "Scroll selection should be allowed when FooterTemplate is null and other conditions are met.");
}

[Fact]
public void IsScrollSelectionAllowed_ReturnsFalse_WhenModeIsDefault()
{
// Arrange: Mode is Default should disable regardless of other fields
var picker = new SfDatePicker
{
Mode = PickerMode.Default,
};
picker.FooterView.Height = 24;
picker.FooterView.ShowOkButton = true;

// Act
var allowed = picker.IsScrollSelectionAllowed();

// Assert
Assert.False(allowed, "Scroll selection should be disallowed when Mode == Default.");
}

[Fact]
public void IsScrollSelectionAllowed_ReturnsFalse_WhenShowOkButtonIsFalse()
{
var picker = new SfDatePicker
{
Mode = PickerMode.Dialog,
};
picker.FooterView.Height = 24;
picker.FooterView.ShowOkButton = false;

var allowed = picker.IsScrollSelectionAllowed();

Assert.False(allowed, "Scroll selection should be disallowed when FooterView.ShowOkButton is false.");
}

#endregion
}
}
Loading