| name | avalonia-services |
| description | Use when accessing Avalonia platform services via TopLevel: clipboard read/write, file/folder/save dialogs via StorageProvider, URI/file launching via Launcher, screen and window info, focus manager, in-app notifications via WindowNotificationManager, or IME input method access. |
Avalonia Platform Services
Overview
Platform services are accessed via the TopLevel class (root of visual tree — typically Window or PopupRoot).
var topLevel = TopLevel.GetTopLevel(this);
Returns null if control is not yet attached to visual tree. Call in OnAttachedToVisualTree or later.
Clipboard
var clipboard = TopLevel.GetTopLevel(this)?.Clipboard;
await clipboard!.SetTextAsync("Hello, world");
var data = new DataObject();
data.Set("application/x-myformat", myObject);
data.Set(DataFormats.Text, "fallback text");
await clipboard.SetDataObjectAsync(data);
var text = await clipboard!.GetTextAsync();
var formats = await clipboard!.GetFormatsAsync();
var raw = await clipboard!.GetDataAsync("application/x-myformat");
await clipboard!.ClearAsync();
File Dialogs (StorageProvider)
var storage = TopLevel.GetTopLevel(this)?.StorageProvider;
Open file(s):
var files = await storage!.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = "Open File",
AllowMultiple = false,
FileTypeFilter = new[]
{
new FilePickerFileType("Images")
{
Patterns = new[] { "*.png", "*.jpg", "*.jpeg", "*.webp" },
MimeTypes = new[] { "image/png", "image/jpeg" }
},
new FilePickerFileType("All Files") { Patterns = new[] { "*" } }
},
SuggestedStartLocation = await storage.TryGetWellKnownFolderAsync(WellKnownFolder.Pictures)
});
if (files.Count > 0)
{
await using var stream = await files[0].OpenReadAsync();
var bitmap = new Bitmap(stream);
}
Built-in FilePickerFileTypes: All, TextPlain, Pdf, Images
Save file:
var file = await storage!.SaveFilePickerAsync(new FilePickerSaveOptions
{
Title = "Save As",
DefaultExtension = "txt",
SuggestedFileName = "untitled",
FileTypeChoices = new[]
{
new FilePickerFileType("Text Files") { Patterns = new[] { "*.txt" } },
new FilePickerFileType("All Files") { Patterns = new[] { "*" } }
}
});
if (file is not null)
{
await using var stream = await file.OpenWriteAsync();
await using var writer = new StreamWriter(stream);
await writer.WriteAsync(content);
}
Open folder:
var folders = await storage!.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = "Select Folder",
AllowMultiple = false,
SuggestedStartLocation = await storage.TryGetWellKnownFolderAsync(WellKnownFolder.Documents)
});
if (folders.Count > 0)
{
var path = folders[0].Path.LocalPath;
}
Well-known folders:
Desktop, Documents, Downloads, Music, Pictures, Videos
Navigate to path:
var folder = await storage.TryGetFolderFromPathAsync("/home/user/projects");
var file = await storage.TryGetFileFromPathAsync("/home/user/file.txt");
Launcher (Open URLs / Files)
var launcher = TopLevel.GetTopLevel(this)?.Launcher;
await launcher!.LaunchUriAsync(new Uri("https://avaloniaui.net"));
await launcher!.LaunchFileAsync(myStorageFile);
Screen Information
var screens = TopLevel.GetTopLevel(this)?.Screens;
var primary = screens?.Primary;
var all = screens?.All;
var count = screens?.ScreenCount;
var bounds = primary?.Bounds;
var workArea = primary?.WorkingArea;
var scaling = primary?.Scaling;
var isPrimary = primary?.IsPrimary;
Window position relative to screen:
if (this is Window window)
{
var position = window.Position;
var size = window.ClientSize;
window.WindowState = WindowState.Maximized;
}
Focus Manager
var fm = TopLevel.GetTopLevel(this)?.FocusManager;
var focused = fm?.GetFocusedElement();
fm?.Focus(myControl, NavigationMethod.Pointer);
myControl.Focus(NavigationMethod.Tab);
In-App Notifications
Requires NuGet: Avalonia.Controls.Notifications
using Avalonia.Controls.Notifications;
private WindowNotificationManager? _notifications;
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
_notifications = new WindowNotificationManager(TopLevel.GetTopLevel(this))
{
Position = NotificationPosition.TopRight,
MaxItems = 3,
Margin = new Thickness(0, 0, 15, 40)
};
}
_notifications?.Show(new Notification(
title: "Success",
message: "File saved successfully.",
type: NotificationType.Success,
expiration: TimeSpan.FromSeconds(4),
onClick: () => Console.WriteLine("Clicked"),
onClose: () => Console.WriteLine("Dismissed")));
NotificationType: Information, Success, Warning, Error
NotificationPosition: TopLeft, TopCenter, TopRight, BottomLeft, BottomCenter, BottomRight
Input Method (IME)
var inputMethod = TopLevel.GetTopLevel(this)?.InputMethod;
inputMethod?.SetCursorRect(new Rect(x, y, 0, lineHeight));
Insider Info: TopLevel Properties Summary
| Property | Type | Purpose |
|---|
Clipboard | IClipboard? | Read/write clipboard |
StorageProvider | IStorageProvider? | File/folder dialogs |
Launcher | ILauncher? | Open URIs and files |
Screens | IScreens? | Screen geometry/DPI |
FocusManager | IFocusManager? | Focus control |
InputMethod | IInputMethod? | IME cursor position |
PlatformSettings | IPlatformSettings? | OS theme, animation prefs |
RendererDiagnostics | RendererDiagnostics | FPS overlay, dirty rects |
Platform settings (dark mode, animations):
var settings = TopLevel.GetTopLevel(this)?.PlatformSettings;
var isDark = settings?.GetColorValues().ThemeVariant == PlatformThemeVariant.Dark;
var reduceMotion = settings?.GetColorValues().ContrastPreference == ColorContrastPreference.High;
Community Dialog & Notification Libraries
The built-in StorageProvider handles file dialogs. For richer dialogs and notifications:
| Library | NuGet | Purpose |
|---|
| MessageBox.Avalonia | MsgBox.Avalonia | Simple message box dialogs (missing from Avalonia core) |
| DialogHost.Avalonia | DialogHost.Avalonia | Material-style async overlay dialogs |
| Movere | GitHub: jp2masa/Movere | Managed dialog service with MVVM support |
| JamSoft.AvaloniaUI.Dialogs | JamSoft.AvaloniaUI.Dialogs | MVVM dialog service + Wizard control |
| HanumanInstitute.MvvmDialogs | HanumanInstitute.MvvmDialogs.Avalonia | Open dialogs from ViewModel without code-behind |
| Jc.PopupView.Avalonia | GitHub: jcsawyer/Jc.PopupView.Avalonia | Animated toasts, alerts, popups |
| Notification.Avalonia | Notification.Avalonia | LINQ-style in-app notification display |
Platform Essentials (MAUI-like APIs)
| Library | Platform | Purpose |
|---|
| Avae.Windows.Essentials | Windows | MAUI Essentials APIs on Windows |
| Avae.macOS.Essentials | macOS | MAUI Essentials APIs on macOS |
| Avae.Linux.Essentials | Linux | MAUI Essentials APIs on Linux |
| Avae.Browser.Essentials | WASM | MAUI Essentials APIs in browser |
Common Mistakes
TopLevel.GetTopLevel(this) returns null before attachment — never call in constructor; use OnAttachedToVisualTree or control-loaded events
IStorageFile is not a file path — must use OpenReadAsync()/OpenWriteAsync() streams; file.Path.LocalPath may fail on sandboxed platforms (iOS/Android/browser)
- Clipboard operations must be awaited — fire-and-forget silently fails or throws on some platforms
WindowNotificationManager created per-notification — creates multiple overlapping managers; create once and store as field
WindowNotificationManager must be created on UI thread — don't create from background tasks
LaunchUriAsync for file:// URIs — use LaunchFileAsync with IStorageFile instead for local files