Skip to content

Close #23: Classic.Avalonia does not build with Avalonia UI 12#28

Open
definability wants to merge 11 commits into
BAndysc:masterfrom
definability:fix/23
Open

Close #23: Classic.Avalonia does not build with Avalonia UI 12#28
definability wants to merge 11 commits into
BAndysc:masterfrom
definability:fix/23

Conversation

@definability

@definability definability commented May 27, 2026

Copy link
Copy Markdown

Avalonia 12 has been released
https://avaloniaui.net/blog/avalonia-12

Note: I suggest checking and merging these pull requests first
because they provide, I believe, useful improvements for Avalonia 11 users
who do not plan to migrate to Avalonia 12 in the near future:

I have split the fix into multiple commits and left descriptive commit messages.
It may be easier to explore the PR commit by commit.
The text below is mostly a concatenation of the commit descriptions.
Hopefully, it can answer questions for reviewers and those willing to migrate their controls from Avalonia 11 to Avalonia 12.

Trivial changes

Use Avalonia 12.0.1.
Avalonia 12.0.0 had a security issue
AvaloniaUI/Avalonia#21122
Use Avalonia.Dock and Avalonia.DataGrid 12.0.0, because there are no 12.0.1 versions for these packages.

Only .NET 8 and later are supported.
However, AvaloniaVisualBasic.Browser does not compile with .NET 8 for browser, so its target framework is .NET 10 now.
Remove AoT conditions for .NET Standard 2.0 and make the corresponding projects AoT-compatible by default.
https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#net-support-updated

Remove built-in COM support.
Tt was necessary before Avalonia 12 and can be removed now
https://docs.avaloniaui.net/docs/deployment/native-aot#project-configuration

Package Avalonia.Diagnostics is removed in Avalonia 12, so

Avalonia.Data.Core.Plugins.BindingPlugins is internal now
and the data annotations plugin is now disabled by default.
Seems like there is no need (and possibility) to remove data validators manually anymore.
https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#binding-plugins

There is no Dock.Serializer package anymore. Use Dock.Serializer.SystemTextJson instead.
https://github.com/wieslawsoltes/Dock#nuget

VisualExtensions.GetVisualRoot was removed. Use TopLevel.GetTopLevel instead.
https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#toplevel

Method VisualLayerManager.IsPopup did not have a detailed description before
https://api-docs.avaloniaui.net/docs/P_Avalonia_Controls_Primitives_VisualLayerManager_IsPopup
There is no clear description of this change, but the corresponding pull request just replaced IsPopup="True" with Name="PART_VisualLayerManager".
Do the same in the Classic theme
AvaloniaUI/Avalonia#20905

In some places, using CompiledBinding causes the following error:

Error AVLN3000 Avalonia: Unable to find suitable setter or adder for property Path of type Avalonia.Base:Avalonia.Data.CompiledBinding for argument System.Runtime:System.String
Replace them with Binding.

ItemCollection.Items became read-only long ago.
Now, ToolPinnedControl and ItemsControl have to use ItemsSource instead
AvaloniaUI/Avalonia@18daa4c

Less trivial changes

Window.ExtendClientAreaToDecorationsChanged method has been made private, so disabling rounded corners cannot be placed there anymore.
Override Window.OnOpened instead because WindowBase.OnOpened is called in WindowBase.Show after PlatformImpl.Show, which calls the chain
WindowImpl.ShowWindow -> WindowImpl.ExtendClientArea -> WindowImpl.ExtendClientAreaToDecorationsChanged.
Thus, if HWND is available in ExtendClientAreaToDecorationsChanged, it should be available by the time OnOpened is called.
WindowBase.IsVisibleChanged also calls WindowBase.Show, but I believe it is enough to modify the corner preference once.
AvaloniaUI/Avalonia#20976

TopLevel.PlatformSettings property is now private and VisualExtensions.GetPlatformSettings should be used instead
https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#toplevel
Read more here:
https://docs.avaloniaui.net/docs/services/platform-settings

Class WindowDecorations was replaced by SystemDecorations.
https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#window-decorations

ExtendClientAreaChromeHints enumeration was completely removed.
My guess: the current default behavior is equivalent to using NoChrom in Avalonia 11
AvaloniaUI/Avalonia#20770

Icons

SKPaint.FilterQuality is obsolete and recommends using SKSamplingOptions instead.
ToSKFilterQuality extension method was completely removed
AvaloniaUI/Avalonia#18981

Use ToSKSamplingOptions instead and provide it to methods that support it.
DrawBitmap does not support the sampling argument,
so convert the bitmap to an image and use DrawImage.

The Final Boss: Window Decorations

Modify CaptionButtonsEx and MDICaptionButtons using Avalonia.Controls.Chrome.WindowDrawnDecorations as the reference:

Fix Avalonia Explorer

Use Avalonia.Controls.Webview instead of WebView.Avalonia and WebView.Avalonia.Desktop.
The first reason: The last version of WebView.Avalonia is 11.0.0.1 (as per today), and does not support Avalonia 12
https://www.nuget.org/packages/WebView.Avalonia
The second reason: Avalonia WebView is open source now
https://avaloniaui.net/blog/the-avalonia-webview-is-going-open-source

Remove UseDesktopWebView and AvaloniaWebViewBuilder as they were only required by the WebViews.Avalonia package
https://github.com/MicroSugarDeveloperOrg/Webviews.Avalonia

Replace WebView with NativeWebView control
https://docs.avaloniaui.net/controls/web/nativewebview

The trickiest part is porting MainWindow.axaml.cs.

  • Remove unnecessary usings.
  • Use the appropriate event listeners in the constructor.
  • Use appropriate parameters (WebView.Source instead of WebView.Url, e.Request instead of e.Url, and so on).
  • Load the home page in the constructor because the native web view does not allow doing this through the control parameters.
  • Remove webkit-related code.

Fix WebViewOnWebViewNewWindowRequested:

Avalonia 12 has been released
https://avaloniaui.net/blog/avalonia-12

Use Avalonia 12.0.1.
Avalonia 12.0.0 had a security issue
AvaloniaUI/Avalonia#21122
Use Avalonia.Dock and Avalonia.DataGrid 12.0.0, because there are no 12.0.1 versions for these packages.

Only .NET 8 and later are supported.
However, AvaloniaVisualBasic.Browser does not compile with .NET 8 or 10, so its target framework is .NET 10 now.
Remove AoT conditions for .NET Standard 2.0 and make the corresonding projects AoT-compatible by default.
https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#net-support-updated

Package `Avalonia.Diagnostics` is removed in Avalonia 12, so
- Use `AvaloniaUI.DiagnosticsSupport` instead;
- Remove `AttachDevTools()` from each Window;
- Add `AttachDeveloperTools` to the corresponding `App.axaml.cs` instead.
https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#avaloniadiagnostics-package-removed

`Avalonia.Data.Core.Plugins.BindingPlugins` is internal now
and the data annotations plugin is now disabled by default.
Seems like there is no need (and possibility) to remove data validators manually anymore.
https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#binding-plugins

There is no `Dock.Serializer` package anymore. Use `Dock.Serializer.SystemTextJson` instead.
https://github.com/wieslawsoltes/Dock#nuget

`VisualExtensions.GetVisualRoot` was removed. Use `TopLevel.GetTopLevel` instead.
https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#toplevel

Method `VisualLayerManager.IsPopup` did not have detailed description before
https://api-docs.avaloniaui.net/docs/P_Avalonia_Controls_Primitives_VisualLayerManager_IsPopup
There is no clear description of this change, but the corresponding pull request just replaced `IsPopup="True"` with `Name="PART_VisualLayerManager"`.
Do the same in the Classic theme
https://github.com/AvaloniaUI/Avalonia/pull/20905/changes

In some places, using `CompiledBinding` causes the following error:
> Error AVLN3000 Avalonia: Unable to find suitable setter or adder for property Path of type Avalonia.Base:Avalonia.Data.CompiledBinding for argument System.Runtime:System.String
Replace them with `Binding`.

`ItemCollection.Items` became read-only long ago.
Now, `ToolPinnedControl` and `ItemsControl` have to use `ItemsSource` instead
AvaloniaUI/Avalonia@18daa4c
`Window.ExtendClientAreaToDecorationsChanged` method has been made `private`, so disabling rounded cordenrs cannot be placed there anymore.
Override `Window.OnOpened` instead because `WindowBase.OnOpened` is called in `WindowBase.Show` after `PlatformImpl.Show`, which calls the chain `WindowImpl.ShowWindow` -> `WindowImpl.ExtendClientArea`, -> `WindowImpl.ExtendClientAreaToDecorationsChanged`.
Thus, if HWND is available in `ExtendClientAreaToDecorationsChanged`, it should be available by the time `OnOpened` is called.
`WindowBase.IsVisibleChanged` also calls `WindowBase.Show`, but I believe it is enough to modify the corner preference once.
AvaloniaUI/Avalonia#20976

`TopLevel.PlatformSettings` property is now `private` and `VisualExtensions.GetPlatformSettings` should be used instead
https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#toplevel
Read more here:
https://docs.avaloniaui.net/docs/services/platform-settings

Class `WindowDecorations` was replaced by `SystemDecorations`.
https://docs.avaloniaui.net/docs/avalonia12-breaking-changes#window-decorations

`ExtendClientAreaChromeHints` enumeration was completely removed.
My guess: the current default behavior is equivalent to using `NoChrom` in Avalonia 11
AvaloniaUI/Avalonia#20770
`SKPaint.FilterQuality` is obsolete and recommends using `SKSamplingOptions` instead.
`ToSKFilterQuality` extension method was completely removed
AvaloniaUI/Avalonia#18981

Use `ToSKSamplingOptions` instead and provide it to methods that support it.
`DrawBitmap` does not support `sampling` argument,
so convert the bitmap to an image and use `DrawImage`.
Use `Avalonia.Controls.Webview` instead of `WebView.Avalonia` and `WebView.Avalonia.Desktop`.
The first reason: The last version of WebView.Avalonia is 11.0.0.1 (as per today), and does not support Avalonia 12
https://www.nuget.org/packages/WebView.Avalonia
The second reason: Avalonia WebView is open source now
https://avaloniaui.net/blog/the-avalonia-webview-is-going-open-source

Remove `UseDesktopWebView` and `AvaloniaWebViewBuilder` as they were only required by the WebViews.Avalonia package
https://github.com/MicroSugarDeveloperOrg/Webviews.Avalonia

Replace `WebView` with `NativeWebView` control
https://docs.avaloniaui.net/controls/web/nativewebview

The trickiest part is to port the `MainWindow.axaml.cs`.

- Remove unnecessary usings.
- Use the appropriate event listeners in the constructor.
- Use appropriate parameters (`WebView.Source` instead of `WebView.Url`, `e.Request` instead of `e.Url`, and so on).
- Load the home page in the constructor because native web view does not allow doing this through the control parameters.
- Remove webkit-related code.

Fix `WebViewOnWebViewNewWindowRequested`:
- `WebViewNewWindowEventArgs.Request` may be null, so check whether this is the case.
- The new window needs its own data context. Create it manually for now rather than using DI.
- Set `Handled` to `true` as in the example
https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.webview.newwindowrequested?view=winrt-28000#examples
- Use `net10.0` instead of `net9.0` as .NET 10 came out and it is an LTS,
  while .NET 9 was an STS release that has already passed through its maintenance phase.
- Leave `net8.0` in examples as the minimum required versions
  for the users to adjust according to their needs locally.
- Update GitHub workflows configuration files.
It looks like `VisualLayerManager` must be the root component
AvaloniaUI/Avalonia#8052

The problem analysis:
When there is nothing above the menu, hovering works fine.
When the menu is not at the top (for example, a panel or a margin added),
the hover location seems to be shifted too:
for example, a 10px shift leads to hover being detected 10px below the menu top.

Removing the visual layer manager helped as well,
but moving it to the root looks like a better solution.
Modify `CaptionButtonsEx` and `MDICaptionButtons` using `Avalonia.Controls.Chrome.WindowDrawnDecorations` as the reference:
- Enumerate parts and pseudoclasses with attributes.
- Find the required buttons by name and store them to subscribe click events on attach and unsubscribe on detach.
- Subscribe to window state actions in `CaptionButtonsEx` like `MDICaptionButtons` does.
- Use named constants instead of magical ones.
https://github.com/AvaloniaUI/Avalonia/blob/42bba0b859cc27082b3db980ccca8c5e5b3534a9/src/Avalonia.Controls/Chrome/WindowDrawnDecorations.cs

- Remove `ChromeOverlayLayer` and `TitleBar.axaml` because they were removed in Avalonia UI 12.
- Use `CaptionButtonsEx` instead of `CaptionButtons` because it was removed in Avalonia UI 12
AvaloniaUI/Avalonia#20770

- Move `VisualLayerManager` to the root.
- Move `CompositeDisposable` from `AutoAttachTitleBar` to a separate file to be accessible for other controls.
# Conflicts:
#	src/Classic.Avalonia.Theme.ColorPicker/Classic.Avalonia.Theme.ColorPicker.csproj
#	src/Classic.Avalonia.Theme.DataGrid/Classic.Avalonia.Theme.DataGrid.csproj
#	src/Classic.Avalonia.Theme.Dock/Classic.Avalonia.Theme.Dock.csproj
#	src/Classic.Avalonia.Theme.Dock/Controls/HostWindow.axaml
#	src/Classic.Avalonia.Theme/Classic.Avalonia.Theme.csproj
#	src/Classic.Avalonia.Theme/Styles/OverlayPopupHost.axaml
#	src/Classic.Avalonia.Theme/Styles/PopupRoot.axaml
#	src/Classic.Avalonia.Theme/Styles/Window.axaml
#	src/Classic.CommonControls.Avalonia/Classic.CommonControls.Avalonia.csproj
# Conflicts:
#	src/Classic.Avalonia.Theme/Styles/Window.axaml
@definability definability force-pushed the fix/23 branch 2 times, most recently from 76859e2 to 018012f Compare May 27, 2026 19:49
@definability

Copy link
Copy Markdown
Author

@BAndysc, please have a look once you have time

- .NET 9.0 was an STS release. We have .NET 10 already.
- `BuiltInComInteropSupport` was necessary before Avalonia 12, so can be removed now
https://docs.avaloniaui.net/docs/deployment/native-aot#project-configuration
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant