Avalonia UI
repository·main·Indexed 12 days ago
https://github.com/avaloniaui/avaloniaA cross-platform XAML-based UI framework for .NET supporting Windows, macOS, Linux, iOS, Android, and WebAssembly. It features a flexible styling system and tools like Avalonia.NameGenerator for strongly-typed XAML references. The framework includes specialized implementations for Wayland architecture and COM object lifetime management in Avalonia.Native.
What's inside Avalonia
- Avalonia is a cross-platform UI framework for .NET that provides a flexible styling system. It supports Windows, macOS, Linux, iOS, Android, and WebAssembly. It is designed as a modern, cross-platform successor to WPF, offering a familiar XAML-based development experience with significant improvements.
Choose between InitializeComponent and OnlyProperties modes
mainThe
AvaloniaNameGeneratorBehaviorsetting changes how the generator interacts with your code-behind class:InitializeComponent(Default): The generator creates anInitializeComponentmethod that performs the actualFindNameScope().Find<T>(...)calls to assign the controls to fields.- Warning: If you use this mode, do not manually define a method named
InitializeComponentin your partial class, as it will hide the generated one. If you must have your ownInitializeComponent, switch the behavior toOnlyProperties.
- Warning: If you use this mode, do not manually define a method named
OnlyProperties: The generator creates get-only properties that callFindNameScope().Find<T>(...)every time they are accessed. This mode is useful if you prefer to manage the lifecycle/loading of your XAML manually.
Follow threading rules for Wayland development
mainAvalonia enforces a strict Messaging Only policy for cross-thread communication between the UI thread and the Wayland thread.
Rules for developers:
- No Cross-Thread Variable Access: UI thread objects must NEVER directly access fields of Wayland-thread objects. Conversely, Wayland thread objects must NEVER directly read fields of UI-thread objects (do not use volatile fields, locks, or shared state).
- Communication via Proxies: All communication from the UI thread to the Wayland thread must go through code-generated proxies. These proxies route calls via
WaylandWorker.PostOob()orPostWithCommit()messages. - Server Object Safety: Objects located in the
Server/directory should not have their internal state modified by the UI thread. The UI thread is only permitted to callPostor pass values into server object constructors.
Understand the Wayland platform architecture in Avalonia
mainThe Wayland implementation in Avalonia is designed around the expectation that the compositor may crash and restart during normal usage. To handle this, Avalonia maintains a "persistent" state of surfaces and resources that can be re-uploaded to a new compositor instance upon restart.
Key architectural characteristics:
- Dedicated Threading: The Wayland event loop runs on a dedicated thread which also serves as the Avalonia render thread. This allows the application to react quickly to compositor frame callbacks.
- NWayland Bindings: Avalonia uses
NWaylandfor Wayland protocol bindings. - Command Batching: Most UI-to-Wayland commands are sent as part of composition batches to ensure the Wayland thread works with a consistent view of the UI state.
- Persistence vs. Transience: Resources in the
Server/Persistentdirectory are maintained to handle compositor restarts, while entities inServer/Transientare considered ephemeral and bound to the current connection.
Understand Avalonia API compatibility guarantees
mainAvalonia provides specific API compatibility guarantees to ensure stability across releases. You can find details regarding these guarantees and any known exceptions in the API Compatibility documentation.Follow the COM return value convention
mainTo prevent memory leaks, all COM interface references returned from a call are assumed to have an incremented reference counter. The caller is responsible for calling
Releaseon these references.To avoid the ambiguity of the
IFoo* GetFoo()pattern, all methods defined inavn.idlmust use theHRESULTwith anout-parameterpattern.// WRONG — easy to leak or forget Release: IFoo* GetFoo(); // CORRECT — use HRESULT + out-parameter: HRESULT GetFoo(IFoo** ppv);Implement wl_pointer frame semantics
mainThe
wl_pointerprotocol uses frame-based event delivery. To ensure correct input routing, follow these requirements:- Dispatch Order: All events within a frame (enter, leave, motion, button, axis) must be dispatched in their exact arrival order. For example, if a frame contains a
leavefrom Surface A followed by anenteron Surface B, they must be processed in that order to avoid routing errors. - Axis Event Combination: Multiple
wl_pointer.axisevents within a single frame should be combined (e.g., horizontal and vertical scroll into a single vector), but the resulting event must be dispatched at the correct position in the original sequence. - State Ownership: Frame state (focused sink, position, modifiers, and accumulated events) belongs to the
wl_pointerinstance, not thewl_seat. Eachwl_pointermanages its own independent frame grouping.
- Dispatch Order: All events within a frame (enter, leave, motion, button, axis) must be dispatched in their exact arrival order. For example, if a frame contains a
Manage COM object lifetimes in Avalonia.Native
mainAvalonia.Native uses COM (Component Object Model) for cross-boundary object lifetime management. COM types are typically prefixed with
IAvn(interfaces) orAvn(implementations). All COM objects derive fromIUnknownand use reference counting viaAddRefandRelease.Critical Safety Rule: Never store raw COM pointers in class fields, instance variables, closures, or containers. Raw COM pointers are only permitted as function parameters or local variables within the scope of a single function call.
Getting started with Avalonia framework development
mainThis documentation is intended for developers contributing to the Avalonia framework itself.
- To build Avalonia from source, follow the Building Avalonia guide.
- Before starting development, review the Contributing guidelines.
Note: If you are looking for documentation on how to use the Avalonia framework to build your own applications, please visit the official user documentation at https://docs.avaloniaui.net/.
Use IDEs with Avalonia
mainAvalonia supports Visual Studio, Visual Studio Code, and Rider. You must use a version that supports at least .NET 10 (e.g., Visual Studio 2026 or Rider 2025.3).
When opening the project, choose one of two solution files:
Avalonia.slnx: Contains the full project (desktop, mobile, and web). Requires all relevant .NET workloads to be installed.Avalonia.Desktop.slnf: A solution filter that opens only the desktop-related parts of Avalonia. This does not require extra workloads.
Build and run the
ControlCatalog.Desktopproject to see the sample application in action.Build and run the ControlCatalog sample
mainTo verify your build, navigate to the desktop control catalog sample and run it:
cd samples\ControlCatalog.Desktop dotnet restore dotnet runUse Avalonia Nightly Builds
mainFor access to the latest features and bugfixes before they reach the stable NuGet release, you can use the Avalonia nightly build feed. Note that these builds are less stable than the official releases.