From 9b33ba1ca877e3d5687554c83abafd560898fb6d Mon Sep 17 00:00:00 2001 From: Stephan Kieburg Date: Thu, 10 Oct 2024 12:17:42 +0200 Subject: [PATCH] #84 - Workaround for DatePicker and TimePicker controls not being able to set to value present in wrapped MAUI control --- .../Controls/DatePickerField.cs | 15 ++++++----- .../Controls/TimePickerField.cs | 7 ++--- .../Controls/DatePickerWrappedView.cs | 27 +++++++++++++++++++ .../Controls/TimePickerWrappedView.cs | 25 +++++++++++++++++ 4 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 src/UraniumUI/Controls/DatePickerWrappedView.cs create mode 100644 src/UraniumUI/Controls/TimePickerWrappedView.cs diff --git a/src/UraniumUI.Material/Controls/DatePickerField.cs b/src/UraniumUI.Material/Controls/DatePickerField.cs index d8aac225..c22440f9 100644 --- a/src/UraniumUI.Material/Controls/DatePickerField.cs +++ b/src/UraniumUI.Material/Controls/DatePickerField.cs @@ -1,5 +1,6 @@ using Plainer.Maui.Controls; using System.ComponentModel; +using UraniumUI.Controls; using UraniumUI.Pages; using UraniumUI.Resources; using UraniumUI.Views; @@ -10,8 +11,8 @@ namespace UraniumUI.Material.Controls; [ContentProperty(nameof(Validations))] public class DatePickerField : InputField { - public DatePickerView DatePickerView => Content as DatePickerView; - public override View Content { get; set; } = new DatePickerView + public DatePickerWrappedView DatePickerView => Content as DatePickerWrappedView; + public override View Content { get; set; } = new DatePickerWrappedView { VerticalOptions = LayoutOptions.Center, #if ANDROID @@ -44,11 +45,11 @@ public DatePickerField() UpdateClearIconState(); - DatePickerView.SetBinding(DatePickerView.DateProperty, new Binding(nameof(Date), source: this)); - DatePickerView.SetBinding(DatePickerView.IsEnabledProperty, new Binding(nameof(IsEnabled), source: this)); - DatePickerView.SetBinding(DatePickerView.FontSizeProperty, new Binding(nameof(FontSize), source: this)); - DatePickerView.SetBinding(DatePickerView.FontAutoScalingEnabledProperty, new Binding(nameof(FontAutoScalingEnabled), source: this)); - DatePickerView.SetBinding(DatePickerView.FontFamilyProperty, new Binding(nameof(FontFamily), source: this)); + DatePickerView.SetBinding(DatePicker.DateProperty, new Binding(nameof(Date), source: this)); + DatePickerView.SetBinding(DatePicker.IsEnabledProperty, new Binding(nameof(IsEnabled), source: this)); + DatePickerView.SetBinding(DatePicker.FontSizeProperty, new Binding(nameof(FontSize), source: this)); + DatePickerView.SetBinding(DatePicker.FontAutoScalingEnabledProperty, new Binding(nameof(FontAutoScalingEnabled), source: this)); + DatePickerView.SetBinding(DatePicker.FontFamilyProperty, new Binding(nameof(FontFamily), source: this)); #if MACCATALYST || IOS labelTitle.InputTransparent = true; diff --git a/src/UraniumUI.Material/Controls/TimePickerField.cs b/src/UraniumUI.Material/Controls/TimePickerField.cs index f6707833..308888df 100644 --- a/src/UraniumUI.Material/Controls/TimePickerField.cs +++ b/src/UraniumUI.Material/Controls/TimePickerField.cs @@ -1,5 +1,6 @@ using Plainer.Maui.Controls; using System.ComponentModel; +using UraniumUI.Controls; using UraniumUI.Pages; using UraniumUI.Resources; using UraniumUI.Views; @@ -10,8 +11,8 @@ namespace UraniumUI.Material.Controls; [ContentProperty(nameof(Validations))] public class TimePickerField : InputField { - public TimePickerView TimePickerView => Content as TimePickerView; - public override View Content { get; set; } = new TimePickerView + public TimePickerWrappedView TimePickerView => Content as TimePickerWrappedView; + public override View Content { get; set; } = new TimePickerWrappedView { VerticalOptions = LayoutOptions.Center, #if WINDOWS @@ -195,4 +196,4 @@ public override void ResetValidation() typeof(bool), typeof(TimePickerField), true, propertyChanged: (bindable, oldValue, newValue) => (bindable as TimePickerField).OnAllowClearChanged()); -} \ No newline at end of file +} diff --git a/src/UraniumUI/Controls/DatePickerWrappedView.cs b/src/UraniumUI/Controls/DatePickerWrappedView.cs new file mode 100644 index 00000000..b5d95030 --- /dev/null +++ b/src/UraniumUI/Controls/DatePickerWrappedView.cs @@ -0,0 +1,27 @@ +using Plainer.Maui.Controls; + +namespace UraniumUI.Controls; + +/// +/// TODO Revisit when the underlying dotnet/maui issue is fixed: https://github.com/dotnet/maui/issues/13156 +/// A workaround for abovementioned issue where the DateSelected event is not raised when the date is the same as the current date. +/// This "manually" raises the PropertyChanged event when the date is the same as the current date by briefly setting it to a different time before applying the actual value. +/// Alternatively, this workaround could be implemented in Plainer.Maui.Controls.DatePickerView directly. +/// +public class DatePickerWrappedView : DatePickerView, IDatePicker +{ + DateTime IDatePicker.Date + { + get => Date; + set + { + if (value == Date) + { + Date += TimeSpan.FromDays(1); + } + + Date = value; + OnPropertyChanged(nameof(Date)); + } + } +} diff --git a/src/UraniumUI/Controls/TimePickerWrappedView.cs b/src/UraniumUI/Controls/TimePickerWrappedView.cs new file mode 100644 index 00000000..90154cec --- /dev/null +++ b/src/UraniumUI/Controls/TimePickerWrappedView.cs @@ -0,0 +1,25 @@ +using Plainer.Maui.Controls; + +namespace UraniumUI.Controls; + + +/// +/// See explanation in +/// +public class TimePickerWrappedView : TimePickerView, ITimePicker +{ + TimeSpan ITimePicker.Time + { + get => Time; + set + { + if (value == Time) + { + Time += TimeSpan.FromSeconds(1); + } + + Time = value; + OnPropertyChanged(nameof(Time)); + } + } +}