From 004f6233d8fa7ef4fce25e5dcac502f993fe9722 Mon Sep 17 00:00:00 2001 From: Andy Howard Date: Fri, 11 Sep 2026 16:44:12 +0100 Subject: [PATCH] Maui .NET 10 migration. --- SacsMobileMaui/Maui/Controls/SamDatePicker.cs | 8 ++++---- SacsMobileMaui/Maui/Controls/SamDateTimePicker.cs | 4 ++-- SacsMobileMaui/Maui/Controls/SamTimePicker.cs | 4 ++-- SacsMobileMaui/SacsMobileMaui.csproj | 8 ++++---- SacsMobileMaui/docs/component-reviews.md | 4 ++-- SacsMobileMaui/docs/topics.md | 10 ++++++---- docs/component-reviews.md | 4 ++-- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/SacsMobileMaui/Maui/Controls/SamDatePicker.cs b/SacsMobileMaui/Maui/Controls/SamDatePicker.cs index 7d5b183..bea61e6 100644 --- a/SacsMobileMaui/Maui/Controls/SamDatePicker.cs +++ b/SacsMobileMaui/Maui/Controls/SamDatePicker.cs @@ -1,4 +1,4 @@ -using Sarand.Net.Mobile.Maui.Layouts; +using Sarand.Net.Mobile.Maui.Layouts; using Sarand.Net.Mobile.Maui.Views; using Sarand.Net.Standard.Base.Utils; using System; @@ -83,12 +83,12 @@ namespace Sarand.Net.Mobile.Maui.Controls } public DateTime MinimumDate { - get { return pickerDate.MinimumDate; } + get { return pickerDate.MinimumDate ?? DateTime.MinValue; } set { pickerDate.MinimumDate = value; } } public DateTime MaximumDate { - get { return pickerDate.MaximumDate; } + get { return pickerDate.MaximumDate ?? DateTime.MaxValue; } set { pickerDate.MaximumDate = value; } } //------------------------------------------------------------------- @@ -98,7 +98,7 @@ namespace Sarand.Net.Mobile.Maui.Controls get { if (invalidDate) return DateTime.MinValue; - return pickerDate.Date; + return pickerDate.Date ?? DateTime.MinValue; } set { diff --git a/SacsMobileMaui/Maui/Controls/SamDateTimePicker.cs b/SacsMobileMaui/Maui/Controls/SamDateTimePicker.cs index 52e731c..443cdb9 100644 --- a/SacsMobileMaui/Maui/Controls/SamDateTimePicker.cs +++ b/SacsMobileMaui/Maui/Controls/SamDateTimePicker.cs @@ -1,4 +1,4 @@ -using Sarand.Net.Mobile.Maui.Layouts; +using Sarand.Net.Mobile.Maui.Layouts; using Sarand.Net.Mobile.Maui.Views; using Sarand.Net.Standard.Base.Utils; using System; @@ -72,7 +72,7 @@ namespace Sarand.Net.Mobile.Maui.Controls // Control value. public DateTime DateTime { - get { return pickerDate.Date.Date + pickerTime.Time; } + get { return pickerDate.Date.Date + (pickerTime.Time ?? TimeSpan.Zero); } set { if (DateTime.CompareTo(value) == 0) return; diff --git a/SacsMobileMaui/Maui/Controls/SamTimePicker.cs b/SacsMobileMaui/Maui/Controls/SamTimePicker.cs index 6718681..3ebaade 100644 --- a/SacsMobileMaui/Maui/Controls/SamTimePicker.cs +++ b/SacsMobileMaui/Maui/Controls/SamTimePicker.cs @@ -1,4 +1,4 @@ -using Sarand.Net.Standard.Base.Utils; +using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; using System.Linq; @@ -27,7 +27,7 @@ namespace Sarand.Net.Mobile.Maui.Controls //------------------------------------------------------------------- // Properties. - public String FormattedTime { get { return DateUtil.Format(DateTime.Today + Time, Format); } } + public String FormattedTime { get { return DateUtil.Format(DateTime.Today + (Time ?? TimeSpan.Zero), Format); } } // Styling. public double DefaultFontSize { get; } diff --git a/SacsMobileMaui/SacsMobileMaui.csproj b/SacsMobileMaui/SacsMobileMaui.csproj index b53d120..d0a02d0 100644 --- a/SacsMobileMaui/SacsMobileMaui.csproj +++ b/SacsMobileMaui/SacsMobileMaui.csproj @@ -1,8 +1,8 @@ - net9.0-android;net9.0-ios;net9.0-maccatalyst18.0 - $(TargetFrameworks);net9.0-windows10.0.19041.0 + net10.0-android;net10.0-ios;net10.0-maccatalyst + $(TargetFrameworks);net10.0-windows10.0.19041.0 true @@ -20,8 +20,8 @@ - - + + diff --git a/SacsMobileMaui/docs/component-reviews.md b/SacsMobileMaui/docs/component-reviews.md index 0fcc11f..609452b 100644 --- a/SacsMobileMaui/docs/component-reviews.md +++ b/SacsMobileMaui/docs/component-reviews.md @@ -7,8 +7,8 @@ table td { } -Last updated: 2026-09-10 +Last updated: 2026-09-11 | Component | Scope | Status | Date reviewed | Next steps | Notes | |---|---|---|---|---|---| -| `SacsMobileMaui` | Project | Reviewed; action required | 2026-09-10 | Address the MAUI 10 migration and focused defects recorded in `topics.md`, then build Windows/Android and validate Apple targets on a Mac. | The project targets unsupported MAUI 9.0.120 while its Sandalwood and Sandtrap consumers still target MAUI 8. Review found compatibility API debt, UI-thread synchronization defects, incorrect handler casts, an `AllowInvalid` setter bug, and discarded resource streams. Local validation was limited by an inconsistent installed workload manifest and write-protected existing `obj` output. | +| `SacsMobileMaui` | Project | .NET 10 migration complete; follow-up required | 2026-09-11 | Migrate Sandtrap and Sandalwood, validate Apple targets on a Mac, then address the compatibility APIs and focused defects recorded in `topics.md`. | The project targets .NET 10 with MAUI 10.0.20. Windows and Android Debug builds pass with zero errors. Nullable picker changes are handled while preserving the controls' existing non-null public API. Compatibility API, UI-thread synchronization, handler-cast, `AllowInvalid`, and resource-stream work remains tracked. | diff --git a/SacsMobileMaui/docs/topics.md b/SacsMobileMaui/docs/topics.md index 6ac26d6..1939af5 100644 --- a/SacsMobileMaui/docs/topics.md +++ b/SacsMobileMaui/docs/topics.md @@ -7,14 +7,14 @@ table td { } -Last updated: 2026-09-10 +Last updated: 2026-09-11 ## Prioritised Topics to Be Actioned | Priority | Topic | Date noted | Next step | Notes | |---|---|---|---|---| -| P1 | Repair the MAUI workload and capture the pre-migration mobile baseline | 2026-09-10 | Repair the inconsistent Android workload manifests, select the current SDK explicitly, then restore/build Windows and Android and record Apple-platform validation requirements. | Depends on a usable MAUI toolchain and authoritative consumer source control. The current workload reports a missing `microsoft-net-runtime-android-net9` extension; Apple builds require a compatible Mac/Xcode environment. | -| P1 | Upgrade `SacsMobileMaui` and its consumers from unsupported .NET MAUI 8/9 to .NET MAUI 10 | 2026-09-10 | Replace MAUI 9 compatibility APIs, align and validate consumer projects, then retarget to `net10.0` and the current MAUI 10 servicing release. | MAUI 9.0.120 is the final MAUI 9 patch, but MAUI 9 support ended on 2026-05-12. Sandalwood and Sandtrap still target MAUI 8 while referencing the `net9.0` shared project. The shared library also uses removed/deprecated compatibility layouts, `Frame`, `MainPage`, and popup APIs. | +| P1 | Upgrade Sandtrap and Sandalwood to .NET MAUI 10 | 2026-09-10 | Retarget and align each consumer with `SacsMobileMaui`, then build and smoke-test their supported platforms. | The shared library now targets .NET 10 and MAUI 10.0.20. Sandalwood and Sandtrap still require coordinated consumer migrations before Common can remove its temporary .NET 8 targets. | +| P2 | Replace obsolete MAUI compatibility APIs | 2026-09-10 | Replace compatibility layouts, `Frame`, `MainPage`, synchronous popup calls, and deprecated expansion options; then remove `Microsoft.Maui.Controls.Compatibility`. | The .NET 10 Windows and Android builds succeed, but retain compatibility references and report the existing API-obsolescence warnings. | | P1 | Make `SamThreadUtil` and form dialogs genuinely asynchronous and deadlock-safe | 2026-09-10 | Replace synchronous UI-thread bridges with `Task`-returning APIs, update the Sandtrap caller, and add focused tests. | The void `InvokeOnMainThreadSync` overload never waits; the generic overload and `DisplayConfirmSync` block on `Task.Result` and can deadlock on the UI thread. `DisplayAlertSync` also passes an async lambda to `Action`, producing `async void` behavior. | | P2 | Correct MAUI native handler type checks | 2026-09-10 | Use `SamEditor` in editor mappings and `SamPicker` in picker mappings; validate each platform-specific option. | Several editor and every picker option currently cast to the wrong custom control type, so configured native styling is silently skipped. | | P2 | Fix `SamDatePicker.AllowInvalid` state transition | 2026-09-10 | Change the assignment in the equality guard, verify both transitions, and add tests for display and reset behavior. | Setting `AllowInvalid` to `true` returns before refreshing the control; the guard uses `allowInvalidDate = value`. | @@ -35,9 +35,11 @@ Last updated: 2026-09-10 | Priority | Topic | Date noted | Date started | Next step | Notes | |---|---|---|---|---|---| -| P1 | Establish authoritative source control for Sandtrap and Sandalwood | 2026-09-10 | 2026-09-10 | Review each initial import, configure its intended remote, and create the baseline commit. | Separate Git repositories now exist at `PippinApps/Repositories/Sandtrap` and `PippinApps/Repositories/Sandalwood`; baseline guidance and tracking files have been added. Consumer migration work should begin only after their initial imports are safely committed. | ## Completed Topics | Topic | Date noted | Date started | Date completed | Outcome | |---|---|---|---|---| +| Establish authoritative source control for Sandtrap and Sandalwood | 2026-09-10 | 2026-09-10 | 2026-09-10 | Separate repositories were initialized, given baseline guidance and tracking files, committed, and pushed to their remotes. | +| Repair the MAUI workload and validate local targets | 2026-09-10 | 2026-09-11 | 2026-09-11 | SDK 10.0.401 reports coherent .NET 10 Android, iOS, Mac Catalyst, and MAUI Windows workloads. The upgraded shared project restores and builds successfully for Windows and Android; Apple builds still require compatible Mac/Xcode validation. | +| Upgrade `SacsMobileMaui` to .NET MAUI 10 | 2026-09-10 | 2026-09-11 | 2026-09-11 | Retargeted Android, iOS, Mac Catalyst, and Windows to .NET 10; aligned MAUI packages to 10.0.20; and adapted date/time controls to MAUI 10 nullable picker values. Windows and Android Debug builds complete with zero errors. | diff --git a/docs/component-reviews.md b/docs/component-reviews.md index 7e2abde..fccfe0b 100644 --- a/docs/component-reviews.md +++ b/docs/component-reviews.md @@ -7,13 +7,13 @@ table td { } -Last updated: 2026-09-10 +Last updated: 2026-09-11 | Component | Scope | Status | Date reviewed | Next steps | Notes | |---|---|---|---|---|---| | `SaCommonVS.sln` | .NET 8/.NET 10 migration build and tests | Multi-target stage complete; passing with warnings | 2026-09-10 | Address the dependency and .NET 10 warnings, then migrate BusinessMgr against the validated Common targets. | Five non-MAUI libraries and `SacsCoreUnitTests` target `net8.0;net10.0`. The supported solution builds with no errors, and 94 of 94 tests pass on each target. BusinessMgr still builds successfully against the .NET 8 outputs. MAUI remains on .NET 9 and is tracked in its project-specific docs. | | `SacsMobileXamarin` | Migration disposition | Isolated; retained for reference | 2026-09-10 | Keep outside the supported build unless a separately scoped resurrection or migration is approved. | Source is unchanged and available through `SaCommonVS.LegacyXamarin.sln`; see `docs/legacy-xamarin.md`. | -| [`SacsMobileMaui`](../SacsMobileMaui/docs/component-reviews.md) | Project | Tracked in project docs | 2026-09-10 | Continue in the project component register and topic tracker. | Project-specific findings have been moved to `SacsMobileMaui/docs`. | +| [`SacsMobileMaui`](../SacsMobileMaui/docs/component-reviews.md) | Project | .NET 10 migration complete; tracked in project docs | 2026-09-11 | Migrate Sandtrap and Sandalwood, validate Apple targets on a Mac, and continue API cleanup in the project tracker. | The shared project now targets .NET 10 with MAUI 10.0.20; Windows and Android Debug builds pass with zero errors. | | `SacsStandardBase/Base/Procs/SaProcess_Base.cs` | Class | In progress | 2026-09-09 | Complete the Process Base actions recorded in `topics.md`; review derived processes separately for cooperative polling. | Lifecycle state ownership and cancellation lock ordering were changed. Five focused tests pass. Remaining concerns include mixed sync/async execution, durable cancellation outcome, cancellation exception handling, disposal, and status synchronization. | | `SacsStandardBase/Base/Email/SaEmailConsole.cs` | Class | Reviewed; action required | 2026-09-08 | Restore SMTP certificate validation and require the configured TLS mode. Add invalid-certificate and unavailable-TLS tests. | The current SMTP client accepts every server certificate. | | `SacsStandardBase/Base/Helpers/SacsEncryptionHelper.cs` and `SacsStandardBase/Base/Data/SacsAesIvCrypter.cs` | Classes | Reviewed; action required | 2026-09-08 | Design a versioned authenticated-encryption format with legacy migration and tamper tests. | Current CBC encryption is unauthenticated; password-based key derivation uses a fixed salt and low iteration count. |