Maui .NET 10 migration.

This commit is contained in:
Andy Howard
2026-09-11 16:44:12 +01:00
parent 18157a1f40
commit 004f6233d8
7 changed files with 22 additions and 20 deletions
@@ -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.Mobile.Maui.Views;
using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Base.Utils;
using System; using System;
@@ -83,12 +83,12 @@ namespace Sarand.Net.Mobile.Maui.Controls
} }
public DateTime MinimumDate public DateTime MinimumDate
{ {
get { return pickerDate.MinimumDate; } get { return pickerDate.MinimumDate ?? DateTime.MinValue; }
set { pickerDate.MinimumDate = value; } set { pickerDate.MinimumDate = value; }
} }
public DateTime MaximumDate public DateTime MaximumDate
{ {
get { return pickerDate.MaximumDate; } get { return pickerDate.MaximumDate ?? DateTime.MaxValue; }
set { pickerDate.MaximumDate = value; } set { pickerDate.MaximumDate = value; }
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
@@ -98,7 +98,7 @@ namespace Sarand.Net.Mobile.Maui.Controls
get get
{ {
if (invalidDate) return DateTime.MinValue; if (invalidDate) return DateTime.MinValue;
return pickerDate.Date; return pickerDate.Date ?? DateTime.MinValue;
} }
set set
{ {
@@ -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.Mobile.Maui.Views;
using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Base.Utils;
using System; using System;
@@ -72,7 +72,7 @@ namespace Sarand.Net.Mobile.Maui.Controls
// Control value. // Control value.
public DateTime DateTime public DateTime DateTime
{ {
get { return pickerDate.Date.Date + pickerTime.Time; } get { return pickerDate.Date.Date + (pickerTime.Time ?? TimeSpan.Zero); }
set set
{ {
if (DateTime.CompareTo(value) == 0) return; if (DateTime.CompareTo(value) == 0) return;
@@ -1,4 +1,4 @@
using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Base.Utils;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -27,7 +27,7 @@ namespace Sarand.Net.Mobile.Maui.Controls
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Properties. // 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. // Styling.
public double DefaultFontSize { get; } public double DefaultFontSize { get; }
+4 -4
View File
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst18.0</TargetFrameworks> <TargetFrameworks>net10.0-android;net10.0-ios;net10.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks> <TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net10.0-windows10.0.19041.0</TargetFrameworks>
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET --> <!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
<!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> --> <!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> -->
<UseMaui>true</UseMaui> <UseMaui>true</UseMaui>
@@ -20,8 +20,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.120" /> <PackageReference Include="Microsoft.Maui.Controls" Version="10.0.20" />
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.120" /> <PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="10.0.20" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
+2 -2
View File
@@ -7,8 +7,8 @@ table td {
} }
</style> </style>
Last updated: 2026-09-10 Last updated: 2026-09-11
| Component | Scope | Status | Date reviewed | Next steps | Notes | | 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. |
+6 -4
View File
@@ -7,14 +7,14 @@ table td {
} }
</style> </style>
Last updated: 2026-09-10 Last updated: 2026-09-11
## Prioritised Topics to Be Actioned ## Prioritised Topics to Be Actioned
| Priority | Topic | Date noted | Next step | Notes | | 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 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. |
| 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. | | 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. | | 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 | 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`. | | 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 | | 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 ## Completed Topics
| Topic | Date noted | Date started | Date completed | Outcome | | 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. |
+2 -2
View File
@@ -7,13 +7,13 @@ table td {
} }
</style> </style>
Last updated: 2026-09-10 Last updated: 2026-09-11
| Component | Scope | Status | Date reviewed | Next steps | Notes | | 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. | | `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`. | | `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/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/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. | | `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. |