diff --git a/Directory.Build.props b/Directory.Build.props
index 0d831b6a..79bb1839 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -21,8 +21,8 @@
$(NoWarn);NU1603
enable
- 15.0
- 15.0
+ 16.0
+ 16.0
23.0
10.0.17763.0
10.0.17763.0
diff --git a/MauiBells/Calendar/CalendarHandler.cs b/MauiBells/Calendar/CalendarHandler.cs
new file mode 100644
index 00000000..e705640c
--- /dev/null
+++ b/MauiBells/Calendar/CalendarHandler.cs
@@ -0,0 +1,22 @@
+namespace MauiBells.Calendar;
+
+public partial class CalendarHandler
+{
+ public static IPropertyMapper PropertyMapper = new PropertyMapper(ViewMapper)
+ {
+ [nameof(ICalendarView.FirstDayOfWeek)] = MapFirstDayOfWeek,
+ [nameof(ICalendarView.MinDate)] = MapMinDate,
+ [nameof(ICalendarView.MaxDate)] = MapMaxDate,
+ [nameof(ICalendarView.SelectedDate)] = MapSelectedDate,
+ };
+
+ public static CommandMapper CommandMapper = new(ViewCommandMapper);
+
+ public CalendarHandler(IPropertyMapper mapper, CommandMapper? commandMapper = null) : base(mapper, commandMapper)
+ {
+ }
+
+ public CalendarHandler() : this(PropertyMapper, CommandMapper)
+ {
+ }
+}
\ No newline at end of file
diff --git a/MauiBells/Calendar/CalendarView.cs b/MauiBells/Calendar/CalendarView.cs
new file mode 100644
index 00000000..f215bd3e
--- /dev/null
+++ b/MauiBells/Calendar/CalendarView.cs
@@ -0,0 +1,51 @@
+namespace MauiBells.Calendar;
+
+using System.ComponentModel;
+
+public class CalendarView : View, ICalendarView
+{
+ readonly WeakEventManager calendarViewEventManager = new();
+
+ public static readonly BindableProperty FirstDayOfWeekProperty = BindableProperty.Create(nameof(FirstDayOfWeek), typeof(DayOfWeek), typeof(CalendarView), default(DayOfWeek));
+ public static readonly BindableProperty MinDateProperty = BindableProperty.Create(nameof(MinDate), typeof(DateTimeOffset), typeof(CalendarView), DateTimeOffset.MinValue);
+ public static readonly BindableProperty MaxDateProperty = BindableProperty.Create(nameof(MaxDate), typeof(DateTimeOffset), typeof(CalendarView), DateTimeOffset.MaxValue);
+ public static readonly BindableProperty SelectedDateProperty = BindableProperty.Create(nameof(SelectedDate), typeof(DateTimeOffset?), typeof(CalendarView));
+
+ public DayOfWeek FirstDayOfWeek
+ {
+ get => (DayOfWeek)GetValue(FirstDayOfWeekProperty);
+ set => SetValue(FirstDayOfWeekProperty, value);
+ }
+
+ [TypeConverter(typeof(DateTimeOffsetStringConverter))]
+ public DateTimeOffset MinDate
+ {
+ get => (DateTimeOffset)GetValue(MinDateProperty);
+ set => SetValue(MinDateProperty, value);
+ }
+
+ [TypeConverter(typeof(DateTimeOffsetStringConverter))]
+ public DateTimeOffset MaxDate
+ {
+ get => (DateTimeOffset)GetValue(MaxDateProperty);
+ set => SetValue(MaxDateProperty, value);
+ }
+
+ [TypeConverter(typeof(DateTimeOffsetStringConverter))]
+ public DateTimeOffset? SelectedDate
+ {
+ get => (DateTimeOffset?)GetValue(SelectedDateProperty);
+ set => SetValue(SelectedDateProperty, value);
+ }
+
+ public event EventHandler SelectedDateChanged
+ {
+ add => calendarViewEventManager.AddEventHandler(value);
+ remove => calendarViewEventManager.RemoveEventHandler(value);
+ }
+
+ void ICalendarView.OnSelectedDateChanged(DateTimeOffset? selectedDate)
+ {
+ calendarViewEventManager.HandleEvent(this, new SelectedDateChangedEventArgs(selectedDate), nameof(SelectedDateChanged));
+ }
+}
\ No newline at end of file
diff --git a/MauiBells/Calendar/DateTimeOffsetStringConverter.cs b/MauiBells/Calendar/DateTimeOffsetStringConverter.cs
new file mode 100644
index 00000000..fefcade9
--- /dev/null
+++ b/MauiBells/Calendar/DateTimeOffsetStringConverter.cs
@@ -0,0 +1,17 @@
+namespace MauiBells.Calendar;
+
+using System.ComponentModel;
+using System.Globalization;
+
+public class DateTimeOffsetStringConverter : TypeConverter
+{
+ public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
+ {
+ if (value is string valueString)
+ {
+ return DateTimeOffset.Parse(valueString);
+ }
+
+ return DateTimeOffset.MinValue;
+ }
+}
\ No newline at end of file
diff --git a/MauiBells/Calendar/ICalendarView.cs b/MauiBells/Calendar/ICalendarView.cs
new file mode 100644
index 00000000..74b4f280
--- /dev/null
+++ b/MauiBells/Calendar/ICalendarView.cs
@@ -0,0 +1,10 @@
+namespace MauiBells.Calendar;
+
+public interface ICalendarView : IView
+{
+ DayOfWeek FirstDayOfWeek { get; }
+ DateTimeOffset MinDate { get; }
+ DateTimeOffset MaxDate { get; }
+ DateTimeOffset? SelectedDate { get; set; }
+ void OnSelectedDateChanged(DateTimeOffset? selectedDate);
+}
\ No newline at end of file
diff --git a/MauiBells/Calendar/SelectedDateChangedEventArgs.cs b/MauiBells/Calendar/SelectedDateChangedEventArgs.cs
new file mode 100644
index 00000000..fd2311af
--- /dev/null
+++ b/MauiBells/Calendar/SelectedDateChangedEventArgs.cs
@@ -0,0 +1,6 @@
+namespace MauiBells.Calendar;
+
+public class SelectedDateChangedEventArgs(DateTimeOffset? selectedDate) : EventArgs
+{
+ public DateTimeOffset? SelectedDate { get; } = selectedDate;
+}
\ No newline at end of file
diff --git a/MauiBells/MainPage.xaml b/MauiBells/MainPage.xaml
index b2b49ad8..b802fd61 100644
--- a/MauiBells/MainPage.xaml
+++ b/MauiBells/MainPage.xaml
@@ -1,6 +1,7 @@
@@ -16,6 +17,18 @@
Padding="30,0"
VerticalOptions="Center">
+
+
+
+
+
@@ -23,7 +36,7 @@
-
+
@@ -31,19 +44,20 @@
+
+
+
+
-
-
-
diff --git a/MauiBells/MainPage.xaml.cs b/MauiBells/MainPage.xaml.cs
index eab08e15..c65cf9ea 100644
--- a/MauiBells/MainPage.xaml.cs
+++ b/MauiBells/MainPage.xaml.cs
@@ -1,5 +1,6 @@
namespace MauiBells;
+using Calendar;
using Plugin.Maui.Audio;
public sealed partial class MainPage : ContentPage, IDisposable
@@ -66,6 +67,7 @@ private void ShakeDetected(object? sender, EventArgs e)
public void Dispose()
{
+ CalendarView.Handler?.DisconnectHandler();
Accelerometer.Default.ShakeDetected -= ShakeDetected;
Accelerometer.Default.ReadingChanged -= ReadingChanged;
Accelerometer.Default.Stop();
@@ -85,4 +87,9 @@ await Dispatcher.DispatchAsync(() =>
await label.RotateXTo(0, 500);
}
}
+
+ private void CalendarView_OnSelectedDateChanged(object? sender, SelectedDateChangedEventArgs e)
+ {
+ SelectedDateLabel.Text = $"Selected Date: {e.SelectedDate}";
+ }
}
\ No newline at end of file
diff --git a/MauiBells/MauiProgram.cs b/MauiBells/MauiProgram.cs
index 6e0e926f..72ce8598 100644
--- a/MauiBells/MauiProgram.cs
+++ b/MauiBells/MauiProgram.cs
@@ -1,11 +1,17 @@
namespace MauiBells;
+using Calendar;
+
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
- builder.UseMauiApp();
+ builder.UseMauiApp()
+ .ConfigureMauiHandlers(handlers =>
+ {
+ handlers.AddHandler();
+ });
return builder.Build();
}
diff --git a/MauiBells/Platforms/Android/CalendarHandler.cs b/MauiBells/Platforms/Android/CalendarHandler.cs
new file mode 100644
index 00000000..586811a0
--- /dev/null
+++ b/MauiBells/Platforms/Android/CalendarHandler.cs
@@ -0,0 +1,56 @@
+namespace MauiBells.Calendar;
+
+using Microsoft.Maui.Handlers;
+using Calendar = Android.Widget.CalendarView;
+
+public partial class CalendarHandler : ViewHandler
+{
+ protected override Calendar CreatePlatformView()
+ {
+ return new Calendar(Context);
+ }
+ protected override void ConnectHandler(Calendar platformView)
+ {
+ base.ConnectHandler(platformView);
+ platformView.DateChange += PlatformView_SelectedDatesChanged;
+ }
+
+ private void PlatformView_SelectedDatesChanged(object? sender, Calendar.DateChangeEventArgs e)
+ {
+ PlatformView.DateChange -= PlatformView_SelectedDatesChanged;
+ VirtualView.SelectedDate = new DateTime(e.Year, e.Month + 1, e.DayOfMonth, 0,0,0);
+ VirtualView.OnSelectedDateChanged(VirtualView.SelectedDate);
+ PlatformView.DateChange += PlatformView_SelectedDatesChanged;
+ }
+
+ protected override void DisconnectHandler(Calendar platformView)
+ {
+ platformView.DateChange -= PlatformView_SelectedDatesChanged;
+ base.DisconnectHandler(platformView);
+ }
+
+ private static void MapFirstDayOfWeek(CalendarHandler handler, ICalendarView virtualView)
+ {
+ handler.PlatformView.FirstDayOfWeek = (int)virtualView.FirstDayOfWeek;
+ }
+
+ private static void MapMinDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+ handler.PlatformView.MinDate = virtualView.MinDate.ToUnixTimeMilliseconds();
+ }
+
+ private static void MapMaxDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+ handler.PlatformView.MaxDate = virtualView.MaxDate.ToUnixTimeMilliseconds();
+ }
+
+ private static void MapSelectedDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+ if (virtualView.SelectedDate is null)
+ {
+ return;
+ }
+
+ handler.PlatformView.SetDate(virtualView.SelectedDate.Value.ToUnixTimeMilliseconds(), true, true);
+ }
+}
\ No newline at end of file
diff --git a/MauiBells/Platforms/Android/MainActivity.cs b/MauiBells/Platforms/Android/MainActivity.cs
index c272d33a..2669cf18 100644
--- a/MauiBells/Platforms/Android/MainActivity.cs
+++ b/MauiBells/Platforms/Android/MainActivity.cs
@@ -1,7 +1,7 @@
-using Android.App;
-using Android.Content.PM;
+namespace MauiBells;
-namespace MauiBells;
+using Android.App;
+using Android.Content.PM;
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
diff --git a/MauiBells/Platforms/Android/MainApplication.cs b/MauiBells/Platforms/Android/MainApplication.cs
index 724d67df..cf8fae14 100644
--- a/MauiBells/Platforms/Android/MainApplication.cs
+++ b/MauiBells/Platforms/Android/MainApplication.cs
@@ -1,7 +1,7 @@
-using Android.App;
-using Android.Runtime;
+namespace MauiBells;
-namespace MauiBells;
+using Android.App;
+using Android.Runtime;
[Application]
public class MainApplication : MauiApplication
diff --git a/MauiBells/Platforms/MacCatalyst/AppDelegate.cs b/MauiBells/Platforms/MacCatalyst/AppDelegate.cs
index 5dbac25e..80f18208 100644
--- a/MauiBells/Platforms/MacCatalyst/AppDelegate.cs
+++ b/MauiBells/Platforms/MacCatalyst/AppDelegate.cs
@@ -1,6 +1,6 @@
-using Foundation;
+namespace MauiBells;
-namespace MauiBells;
+using Foundation;
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
diff --git a/MauiBells/Platforms/MacCatalyst/CalendarHandler.cs b/MauiBells/Platforms/MacCatalyst/CalendarHandler.cs
new file mode 100644
index 00000000..ee980cf5
--- /dev/null
+++ b/MauiBells/Platforms/MacCatalyst/CalendarHandler.cs
@@ -0,0 +1,31 @@
+namespace MauiBells.Calendar;
+
+using Microsoft.Maui.Handlers;
+using UIKit;
+
+public partial class CalendarHandler : ViewHandler
+{
+ protected override UICalendarView CreatePlatformView()
+ {
+ return new UICalendarView();
+ }
+
+ private static void MapFirstDayOfWeek(CalendarHandler handler, ICalendarView virtualView)
+ {
+
+ }
+ private static void MapMinDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+
+ }
+
+ private static void MapMaxDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+
+ }
+
+ private static void MapSelectedDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/MauiBells/Platforms/MacCatalyst/Program.cs b/MauiBells/Platforms/MacCatalyst/Program.cs
index 7171271a..1704b97a 100644
--- a/MauiBells/Platforms/MacCatalyst/Program.cs
+++ b/MauiBells/Platforms/MacCatalyst/Program.cs
@@ -1,6 +1,6 @@
-using UIKit;
+namespace MauiBells;
-namespace MauiBells;
+using UIKit;
public class Program
{
diff --git a/MauiBells/Platforms/Tizen/CalendarHandler.cs b/MauiBells/Platforms/Tizen/CalendarHandler.cs
new file mode 100644
index 00000000..a0989bb6
--- /dev/null
+++ b/MauiBells/Platforms/Tizen/CalendarHandler.cs
@@ -0,0 +1,30 @@
+namespace MauiBells.Calendar;
+
+using Microsoft.Maui.Handlers;
+
+public partial class CalendarHandler : ViewHandler
+{
+ protected override CalendarView CreatePlatformView()
+ {
+ return new CalendarView();
+ }
+
+ private static void MapFirstDayOfWeek(CalendarHandler handler, ICalendarView virtualView)
+ {
+
+ }
+ private static void MapMinDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+
+ }
+
+ private static void MapMaxDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+
+ }
+
+ private static void MapSelectedDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/MauiBells/Platforms/Windows/CalendarHandler.cs b/MauiBells/Platforms/Windows/CalendarHandler.cs
new file mode 100644
index 00000000..fa5a5474
--- /dev/null
+++ b/MauiBells/Platforms/Windows/CalendarHandler.cs
@@ -0,0 +1,68 @@
+namespace MauiBells.Calendar;
+
+using Windows.Globalization;
+using Microsoft.Maui.Handlers;
+using Microsoft.UI.Xaml.Controls;
+using Calendar = Microsoft.UI.Xaml.Controls.CalendarView;
+
+public partial class CalendarHandler : ViewHandler
+{
+ protected override Calendar CreatePlatformView()
+ {
+ return new Calendar();
+ }
+
+ protected override void ConnectHandler(Calendar platformView)
+ {
+ base.ConnectHandler(platformView);
+ platformView.SelectedDatesChanged += PlatformView_SelectedDatesChanged;
+ }
+
+ private void PlatformView_SelectedDatesChanged(Calendar sender, CalendarViewSelectedDatesChangedEventArgs args)
+ {
+ PlatformView.SelectedDatesChanged -= PlatformView_SelectedDatesChanged;
+ if (args.AddedDates.Count == 0)
+ {
+ VirtualView.SelectedDate = null;
+ }
+
+ if (args.AddedDates.Count > 0)
+ {
+ VirtualView.SelectedDate = args.AddedDates[0];
+ }
+
+ VirtualView.OnSelectedDateChanged(VirtualView.SelectedDate);
+ PlatformView.SelectedDatesChanged += PlatformView_SelectedDatesChanged;
+ }
+
+ protected override void DisconnectHandler(Calendar platformView)
+ {
+ platformView.SelectedDatesChanged -= PlatformView_SelectedDatesChanged;
+ base.DisconnectHandler(platformView);
+ }
+
+ private static void MapFirstDayOfWeek(CalendarHandler handler, ICalendarView virtualView)
+ {
+ handler.PlatformView.FirstDayOfWeek = (DayOfWeek)virtualView.FirstDayOfWeek;
+ }
+
+ private static void MapMinDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+ handler.PlatformView.MinDate = virtualView.MinDate;
+ }
+
+ private static void MapMaxDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+ handler.PlatformView.MaxDate = virtualView.MaxDate;
+ }
+
+ private static void MapSelectedDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+ handler.PlatformView.SelectedDates.Clear();
+ if (virtualView.SelectedDate is not null)
+ {
+ handler.PlatformView.SelectedDates.Add(virtualView.SelectedDate.Value);
+ handler.PlatformView.SetDisplayDate(virtualView.SelectedDate.Value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/MauiBells/Platforms/iOS/AppDelegate.cs b/MauiBells/Platforms/iOS/AppDelegate.cs
index 5dbac25e..80f18208 100644
--- a/MauiBells/Platforms/iOS/AppDelegate.cs
+++ b/MauiBells/Platforms/iOS/AppDelegate.cs
@@ -1,6 +1,6 @@
-using Foundation;
+namespace MauiBells;
-namespace MauiBells;
+using Foundation;
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
diff --git a/MauiBells/Platforms/iOS/CalendarHandler.cs b/MauiBells/Platforms/iOS/CalendarHandler.cs
new file mode 100644
index 00000000..ee980cf5
--- /dev/null
+++ b/MauiBells/Platforms/iOS/CalendarHandler.cs
@@ -0,0 +1,31 @@
+namespace MauiBells.Calendar;
+
+using Microsoft.Maui.Handlers;
+using UIKit;
+
+public partial class CalendarHandler : ViewHandler
+{
+ protected override UICalendarView CreatePlatformView()
+ {
+ return new UICalendarView();
+ }
+
+ private static void MapFirstDayOfWeek(CalendarHandler handler, ICalendarView virtualView)
+ {
+
+ }
+ private static void MapMinDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+
+ }
+
+ private static void MapMaxDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+
+ }
+
+ private static void MapSelectedDate(CalendarHandler handler, ICalendarView virtualView)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/MauiBells/Platforms/iOS/Program.cs b/MauiBells/Platforms/iOS/Program.cs
index 7171271a..1704b97a 100644
--- a/MauiBells/Platforms/iOS/Program.cs
+++ b/MauiBells/Platforms/iOS/Program.cs
@@ -1,6 +1,6 @@
-using UIKit;
+namespace MauiBells;
-namespace MauiBells;
+using UIKit;
public class Program
{
diff --git a/MauiBells/README.md b/MauiBells/README.md
index 96d0bb17..1a0499d2 100644
--- a/MauiBells/README.md
+++ b/MauiBells/README.md
@@ -4,6 +4,12 @@
Article:
+Features:
+
+- Calendar View (Handlers)
+- Animations
+- AudioPlayer
+
## Video
[Video](https://ik.imagekit.io/VladislavAntonyuk/vladislavantonyuk/articles/34/jingle-bells.mp4)
diff --git a/MauiBells/README.mdpp b/MauiBells/README.mdpp
index 22ac9d74..88cdceef 100644
--- a/MauiBells/README.mdpp
+++ b/MauiBells/README.mdpp
@@ -4,6 +4,12 @@
Article:
+Features:
+
+- Calendar View (Handlers)
+- Animations
+- AudioPlayer
+
## Video
[Video](https://ik.imagekit.io/VladislavAntonyuk/vladislavantonyuk/articles/34/jingle-bells.mp4)
diff --git a/MauiBluetooth/MauiBluetooth.csproj b/MauiBluetooth/MauiBluetooth.csproj
index 2ce23a26..cca8fb6d 100644
--- a/MauiBluetooth/MauiBluetooth.csproj
+++ b/MauiBluetooth/MauiBluetooth.csproj
@@ -30,19 +30,4 @@
-
-
- false
-
-
- true
-
-
- true
-
-
- true
-
-
-
diff --git a/README.md b/README.md
index 1475c89b..c8a0840c 100644
--- a/README.md
+++ b/README.md
@@ -57,7 +57,7 @@ The development guide can be found at [SETUP.md](./SETUP.md).
1. [MauiBadge](MauiBadge) - AppIcon Badge.
-1. [MauiBells](MauiBells) - Flip animation, Audio player, Accelerometer.
+1. [MauiBells](MauiBells) - Calendar View (Handlers), Flip animation, Audio player, Accelerometer.
1. [MauiMarkdown](MauiMarkdown) - Create a Markdown control using .NET MAUI Graphics.
diff --git a/README.mdpp b/README.mdpp
index 29f3a0a3..6918751d 100644
--- a/README.mdpp
+++ b/README.mdpp
@@ -57,7 +57,7 @@ The development guide can be found at [SETUP.md](./SETUP.md).
1. [MauiBadge](MauiBadge) - AppIcon Badge.
-1. [MauiBells](MauiBells) - Flip animation, Audio player, Accelerometer.
+1. [MauiBells](MauiBells) - Calendar View (Handlers), Flip animation, Audio player, Accelerometer.
1. [MauiMarkdown](MauiMarkdown) - Create a Markdown control using .NET MAUI Graphics.