Summary
Follow-up to #499. The Avalonia sample's NU1903 (Tmds.DBus.Protocol) was resolved by bumping to the latest Avalonia 11.3.x patch (11.3.18) — no major-version bump was required for that fix. This issue tracks a separate, larger effort: bumping the TodoApp.Avalonia sample from Avalonia 11 to 12 (recommend targeting the latest 12.0.x patch, 12.0.5 as of this writing) for general currency, since 11.x will presumably reach end-of-support once 12 is established.
This is not required to close #499 and should be treated as its own scoped PR with a normal fix/validate/PR cycle.
Scope
All items below were confirmed against the sample's actual source (samples/todoapp/TodoApp.Avalonia/) and the official Avalonia 12 breaking changes doc.
Required changes
- Package versions — bump
Avalonia, Avalonia.Themes.Fluent, Avalonia.Fonts.Inter, Avalonia.Desktop, Avalonia.Android, Avalonia.iOS to 12.0.5 (or later) via the shared $(AvaloniaVersion) property in Directory.Build.props.
Avalonia.Diagnostics package removed in v12 — drop the Debug-only PackageReference from TodoApp.Avalonia.csproj and TodoApp.Avalonia.Desktop.csproj. No code in the sample calls AttachDevTools(), so this is a clean removal (the paid AvaloniaUI.DiagnosticsSupport replacement is an Avalonia Plus feature and likely out of scope for this OSS sample).
App.axaml.cs — binding plugins removed — delete BindingPlugins.DataValidators.RemoveAt(0); and its two Avalonia.Data.Core* usings. The BindingPlugins class no longer exists in v12; behavior is preserved because v12 disables the data-annotations validation plugin by default.
App.axaml.cs — Android lifetime type changed — add an IActivityApplicationLifetime branch (using MainViewFactory) before the existing ISingleViewApplicationLifetime check, since Android now implements the former instead of the latter:
else if (ApplicationLifetime is IActivityApplicationLifetime activityLifetime)
activityLifetime.MainViewFactory = () => new MainView { DataContext = GetRequiredService<TodoListViewModel>() };
- Android app-initialization rework:
- Add a new
TodoApp.Avalonia.Android/Application.cs:
[Application]
public class Application : AvaloniaAndroidApplication<App>
{
protected Application(nint javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { }
protected override AppBuilder CustomizeAppBuilder(AppBuilder builder) => base.CustomizeAppBuilder(builder).WithInterFont();
}
- Change
MainActivity : AvaloniaMainActivity<App> → non-generic MainActivity : AvaloniaMainActivity, removing its CustomizeAppBuilder override (moved above).
- Add
android:name=".Application" to the <application> element in AndroidManifest.xml.
MainView.axaml — rename Watermark="Add a new Item" → PlaceholderText="Add a new Item" (old property kept but obsolete; optional but recommended for cleanliness/future-proofing).
- iOS
AppDelegate.cs — its CustomizeAppBuilder override isn't listed as removed for iOS in the breaking-changes doc, so it should compile unchanged, but this needs a real build to confirm.
Confirmed NOT applicable (verified via source grep — no action needed)
Gestures.* attached events, clipboard/IDataObject APIs, GotFocusEventArgs, WindowState-in-styles, TextBlock.LetterSpacing, SystemDecorations/ExtendClientAreaChromeHints, KeyboardNavigationHandler, custom Screen construction, Direct2D1/Blazor/Tizen backends, headless xUnit/NUnit tests.
Tooling / environment prerequisites
Avalonia.Android 12.0.5 targets net10.0-android36.0 bindings and Avalonia.iOS 12.0.5 targets net10.0-ios26.0/maccatalyst26.0/tvos26.0. The csproj TargetFramework values don't need to change, but the build machine/CI needs current Android API 36 and iOS 26 SDK components (dotnet workload update).
- No CI coverage exists for
/samples at all today (build-library.yml, build-docs.yml, build-template.yml don't touch it), so this migration will ship with manual verification only — build + a real smoke-test run of the Desktop head (add/complete/delete an item, confirm sync + notifications) is strongly recommended given both the validation-plugin behavior and the Android lifetime path are changing. Adding a samples build workflow could be a worthwhile separate follow-up.
Related
Summary
Follow-up to #499. The Avalonia sample's NU1903 (Tmds.DBus.Protocol) was resolved by bumping to the latest Avalonia 11.3.x patch (11.3.18) — no major-version bump was required for that fix. This issue tracks a separate, larger effort: bumping the
TodoApp.Avaloniasample from Avalonia 11 to 12 (recommend targeting the latest 12.0.x patch,12.0.5as of this writing) for general currency, since 11.x will presumably reach end-of-support once 12 is established.This is not required to close #499 and should be treated as its own scoped PR with a normal fix/validate/PR cycle.
Scope
All items below were confirmed against the sample's actual source (
samples/todoapp/TodoApp.Avalonia/) and the official Avalonia 12 breaking changes doc.Required changes
Avalonia,Avalonia.Themes.Fluent,Avalonia.Fonts.Inter,Avalonia.Desktop,Avalonia.Android,Avalonia.iOSto12.0.5(or later) via the shared$(AvaloniaVersion)property inDirectory.Build.props.Avalonia.Diagnosticspackage removed in v12 — drop the Debug-onlyPackageReferencefromTodoApp.Avalonia.csprojandTodoApp.Avalonia.Desktop.csproj. No code in the sample callsAttachDevTools(), so this is a clean removal (the paidAvaloniaUI.DiagnosticsSupportreplacement is an Avalonia Plus feature and likely out of scope for this OSS sample).App.axaml.cs— binding plugins removed — deleteBindingPlugins.DataValidators.RemoveAt(0);and its twoAvalonia.Data.Core*usings. TheBindingPluginsclass no longer exists in v12; behavior is preserved because v12 disables the data-annotations validation plugin by default.App.axaml.cs— Android lifetime type changed — add anIActivityApplicationLifetimebranch (usingMainViewFactory) before the existingISingleViewApplicationLifetimecheck, since Android now implements the former instead of the latter:TodoApp.Avalonia.Android/Application.cs:MainActivity : AvaloniaMainActivity<App>→ non-genericMainActivity : AvaloniaMainActivity, removing itsCustomizeAppBuilderoverride (moved above).android:name=".Application"to the<application>element inAndroidManifest.xml.MainView.axaml— renameWatermark="Add a new Item"→PlaceholderText="Add a new Item"(old property kept but obsolete; optional but recommended for cleanliness/future-proofing).AppDelegate.cs— itsCustomizeAppBuilderoverride isn't listed as removed for iOS in the breaking-changes doc, so it should compile unchanged, but this needs a real build to confirm.Confirmed NOT applicable (verified via source grep — no action needed)
Gestures.*attached events, clipboard/IDataObjectAPIs,GotFocusEventArgs,WindowState-in-styles,TextBlock.LetterSpacing,SystemDecorations/ExtendClientAreaChromeHints,KeyboardNavigationHandler, customScreenconstruction, Direct2D1/Blazor/Tizen backends, headless xUnit/NUnit tests.Tooling / environment prerequisites
Avalonia.Android 12.0.5targetsnet10.0-android36.0bindings andAvalonia.iOS 12.0.5targetsnet10.0-ios26.0/maccatalyst26.0/tvos26.0. The csprojTargetFrameworkvalues don't need to change, but the build machine/CI needs current Android API 36 and iOS 26 SDK components (dotnet workload update)./samplesat all today (build-library.yml,build-docs.yml,build-template.ymldon't touch it), so this migration will ship with manual verification only — build + a real smoke-test run of the Desktop head (add/complete/delete an item, confirm sync + notifications) is strongly recommended given both the validation-plugin behavior and the Android lifetime path are changing. Adding a samples build workflow could be a worthwhile separate follow-up.Related