Files
playbook/skills/thirdparty/ui-ux-pro-max/data/stacks/avalonia.csv
T

27 KiB

1NoCategoryGuidelineDescriptionDoDon'tCode GoodCode BadSeverityDocs URLApplies ToStatusVerified At
21XAMLUse Avalonia XAML namespaceAvalonia has its own XAML namespace not WPFxmlns= for Avalonia-specific namespaceWPF xmlns or UWP xmlns<Window xmlns="https://github.com/avaloniaui"><Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">Highhttps://docs.avaloniaui.net/docs/fundamentals/avalonia-xamlavalonia 12active2026-08-13
32XAMLUse compiled bindings with x:DataTypeEnable compile-time binding validationx:DataType on root or DataTemplate for compiled bindingsReflection-based bindings in production<Window x:DataType="vm:MainViewModel"><TextBlock Text="{Binding Name}"/></Window><Window><TextBlock Text="{Binding Name}"/> without x:DataTypeHighhttps://docs.avaloniaui.net/docs/data-binding/compiled-bindingsavalonia 12active2026-08-13
43XAMLEnable compiled bindings globallyAvalonia 12 enables AvaloniaUseCompiledBindingsByDefault by default so every binding requires x:DataType and remains trim-safe for Native AOTKeep the Avalonia 12 default or set AvaloniaUseCompiledBindingsByDefault explicitly when documenting the project contractDisable compiled bindings or rely on runtime binding resolution<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault><AvaloniaUseCompiledBindingsByDefault>false</AvaloniaUseCompiledBindingsByDefault>Highhttps://docs.avaloniaui.net/docs/data-binding/compiled-bindingsavalonia 12active2026-08-13
54XAMLUse #name shorthand for element-to-element bindingsCompiled bindings cannot resolve {Binding ElementName=...} - use the #name shorthand which relies on NameScope lookup#name shorthand referencing x:Name controls in the same NameScopeElementName binding inside a compiled-binding scope<TextBlock Text="{Binding #SearchBox.Text}"/><TextBlock Text="{Binding ElementName=SearchBox, Path=Text}"/> under compiled bindingsMediumhttps://docs.avaloniaui.net/docs/data-binding/compiled-bindingsavalonia 12active2026-08-13
65StylingUse CSS-like selectorsAvalonia uses selectors not implicit stylesSelectors targeting control types classes and pseudoclassesWPF-style implicit Style with TargetType<Style Selector="Button.primary"><Setter Property="Background" Value="Blue"/></Style><Style TargetType="Button"> without SelectorHighhttps://docs.avaloniaui.net/docs/styling/selectorsavalonia 12active2026-08-13
76StylingUse pseudoclass selectors for statesTarget control states with colon syntax:pointerover :pressed :focus for interactive statesVisualStateManager or Triggers<Style Selector="Button:pointerover"><Setter Property="Opacity" Value="0.8"/></Style><VisualStateManager> for hover effectsMediumhttps://docs.avaloniaui.net/docs/styling/pseudoclassesavalonia 12active2026-08-13
87StylingUse nesting selectorsChild and descendant combinators for scoped styles> for direct child and space for descendantFlat selectors that match too broadly<Style Selector="StackPanel > Button"><Setter Property="Margin" Value="4"/></Style><Style Selector="Button"> that affects all buttons unintentionallyMediumhttps://docs.avaloniaui.net/docs/styling/style-selector-syntaxavalonia 12active2026-08-13
98StylingUse StyleInclude for modularitySplit styles into separate AXAML filesStyleInclude to import themed resource filesAll styles in a single monolithic App.axaml<StyleInclude Source="/Styles/ButtonStyles.axaml"/>1000+ line App.axaml with all stylesMediumhttps://docs.avaloniaui.net/docs/styling/stylesavalonia 12active2026-08-13
109StylingUse Fluent or Simple themeBuilt-in Avalonia themesFluentTheme or SimpleTheme as baseCustom theme from scratch<FluentTheme/>Building all control templates manuallyHighhttps://docs.avaloniaui.net/docs/styling/themesavalonia 12active2026-08-13
1110StylingUse theme variants for dark modeSwitch between light and darkRequestedThemeVariant for theme switchingHardcoded colors ignoring theme variantsApplication.Current.RequestedThemeVariant = ThemeVariant.Dark;Manually changing every brush for dark modeMediumhttps://docs.avaloniaui.net/docs/styling/themesavalonia 12active2026-08-13
1211ControlsUse DataGrid for tabular dataDataGrid is a separate Avalonia.Controls.DataGrid NuGet package and requires its theme StyleInclude in App.axamlDataGrid after adding package and StyleInclude for the matching themeCustom Grid layouts for tabular data or DataGrid without the theme StyleInclude<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False"/> with <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/> in App.axaml<DataGrid/> with no package reference or no StyleInclude (renders unstyled)Mediumhttps://docs.avaloniaui.net/docs/reference/controls/datagrid/avalonia 12active2026-08-13
1312ControlsUse TreeView with TreeDataTemplateAvalonia uses TreeDataTemplate for hierarchical data - HierarchicalDataTemplate is WPF onlyTreeDataTemplate inside TreeView.ItemTemplate with ItemsSource pointing at child collectionHierarchicalDataTemplate copied from WPF or nested ItemsControls<TreeView ItemsSource="{Binding Nodes}"><TreeView.ItemTemplate><TreeDataTemplate ItemsSource="{Binding Children}"><TextBlock Text="{Binding Name}"/></TreeDataTemplate></TreeView.ItemTemplate></TreeView><TreeView><TreeView.ItemTemplate><HierarchicalDataTemplate/></TreeView.ItemTemplate></TreeView> // HierarchicalDataTemplate does not exist in AvaloniaHighhttps://docs.avaloniaui.net/docs/reference/controls/treeview-1avalonia 12active2026-08-13
1413ControlsUse NativeMenu for platform menusNative menu bar on macOS and desktopNativeMenu for cross-platform menu barCustom menu implementation per platform<NativeMenu.Menu><NativeMenu><NativeMenuItem Header="File"/></NativeMenu></NativeMenu.Menu>Custom menu bar control for each platformMediumhttps://docs.avaloniaui.net/docs/reference/controls/nativemenuavalonia 12active2026-08-13
1514Data BindingImplement INotifyPropertyChangedStandard .NET property notificationINotifyPropertyChanged or CommunityToolkit.MvvmProperties without change notification[ObservableProperty] private string _name;public string Name { get; set; } without notificationHighhttps://docs.avaloniaui.net/docs/data-binding/inotifypropertychangedavalonia 12active2026-08-13
1615Data BindingUse ObservableCollection for listsUI updates on collection changesObservableCollection<T> for bound collectionsList<T> for ItemsSourcesObservableCollection<Item> Items { get; } = new();List<Item> Items { get; set; }Highhttps://docs.avaloniaui.net/docs/data-binding/inotifypropertychangedavalonia 12active2026-08-13
1716Data BindingUse binding to named controlsElement-to-element binding with # syntax#ElementName.Property for cross-element bindingCode-behind for element references<TextBlock Text="{Binding #slider.Value, StringFormat='{}{0:F0}'}"/>Code-behind ValueChanged handler to update TextBlockMediumhttps://docs.avaloniaui.net/docs/data-binding/introduction-to-data-bindingavalonia 12active2026-08-13
1817Data BindingUse converters or FuncValueConverterTransform data for displayFuncValueConverter for simple inline conversionsComplex IValueConverter classes for trivial transformspublic static FuncValueConverter<bool, IBrush> BoolToColor = new(b => b ? Brushes.Green : Brushes.Red);Full IValueConverter class for bool to colorMediumhttps://docs.avaloniaui.net/docs/data-binding/how-to-create-a-custom-data-binding-converteravalonia 12active2026-08-13
1918Cross-PlatformUse platform-specific code carefullyIsolate platform code behind abstractionsInterface + platform implementation pattern#if directives scattered through ViewModelsIPlatformService with platform-specific implementations#if WINDOWS ... #elif LINUX ... in ViewModelMediumhttps://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/avalonia 12active2026-08-13
2019Cross-PlatformTest on all target platformsRendering and behavior varies across platformsCI testing on Windows macOS and LinuxTesting only on development platformGitHub Actions matrix with windows-latest ubuntu-latest macos-latestTesting only on Windows assuming cross-platform worksHighhttps://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/avalonia 12active2026-08-13
2120Cross-PlatformHandle platform file pathsPath separators differ across OSPath.Combine and Environment.SpecialFolderHardcoded backslashes or forward slashesPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MyApp")@"C:\Users\data\config.json"Mediumhttps://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/dealing-with-platformsavalonia 12active2026-08-13
2221Cross-PlatformUse Avalonia asset systemPlatform-agnostic resource loadingavares:// URI scheme for embedded resourcesFile system paths for assets<Image Source="avares://MyApp/Assets/logo.png"/><Image Source="C:/images/logo.png"/>Highhttps://docs.avaloniaui.net/docs/fundamentals/including-assetsavalonia 12active2026-08-13
2322PerformanceUse virtualization for large listsOnly render visible itemsListBox and ItemsRepeater with virtualizationNon-virtualizing ItemsControl for large lists<ListBox ItemsSource="{Binding LargeList}"/><ItemsControl><StackPanel> for 10K itemsHighhttps://docs.avaloniaui.net/docs/reference/controls/listboxavalonia 12active2026-08-13
2423PerformanceAvoid unnecessary bindingsEach binding has overheadBind only properties that changeBinding static labels and headers<TextBlock Text="{Binding DynamicTitle}"/> but static: <TextBlock Text="Settings"/><TextBlock Text="{Binding SettingsLabel}"/> for constant stringLowhttps://docs.avaloniaui.net/docs/data-binding/introduction-to-data-bindingavalonia 12active2026-08-13
2524PerformanceSet bitmap interpolation mode on scaled imagesRenderOptions.BitmapInterpolationMode controls image scaling quality vs cost; default may look aliased on upscaled or downscaled bitmapsRenderOptions.SetBitmapInterpolationMode tuned to the use caseDefault interpolation on scaled images that look blurry or aliasedRenderOptions.SetBitmapInterpolationMode(image, BitmapInterpolationMode.HighQuality);Image scaled with Stretch and no interpolation hint setLowhttps://docs.avaloniaui.net/docs/concepts/image-interpolationavalonia 12active2026-08-13
2625PerformanceProfile with Avalonia DevToolsBuilt-in diagnostic toolsDevTools for visual tree and binding inspectionConsole.WriteLine debuggingAttach DevTools in debug mode with F12Print statements to debug layout issuesMediumhttps://docs.avaloniaui.net/docs/guides/implementation-guides/developer-toolsavalonia 12active2026-08-13
2726ArchitectureUse MVVM with ReactiveUI or CommunityToolkitProven MVVM frameworks for AvaloniaReactiveUI or CommunityToolkit.Mvvm for ViewModelsCode-behind for all logicpublic class MainViewModel : ReactiveObject { }MainWindow.axaml.cs with all business logicHighhttps://docs.avaloniaui.net/docs/how-to/mvvm-how-toavalonia 12active2026-08-13
2827ArchitectureUse ViewLocator patternConvention-based View-ViewModel resolutionViewLocator for automatic view resolutionManual view instantiation and DataContext wiringclass ViewLocator : IDataTemplate { Build(object data) => new MainView(); }new MainView { DataContext = new MainViewModel() } everywhereMediumhttps://docs.avaloniaui.net/docs/data-templates/view-locatoravalonia 12active2026-08-13
2928ArchitectureUse dependency injectionRegister services in a Microsoft.Extensions.DependencyInjection container during startup before any view is constructed - resolve ViewModels through the provider not via a static ServiceLocatorBuild the ServiceProvider in BuildAvaloniaApp or OnFrameworkInitializationCompleted then resolve ViewModels from itStatic ServiceLocator or new-ing ViewModels inline in code-behindservices.AddSingleton<IDataService, DataService>(); services.AddTransient<MainViewModel>(); var provider = services.BuildServiceProvider(); // wired before windows are createdServiceLocator.Current.GetInstance<IDataService>() called from random ViewModels with no registration orderingMediumhttps://docs.avaloniaui.net/docs/app-development/dependency-injectionavalonia 12active2026-08-13
3029ArchitectureSeparate Views from ViewModelsKeep UI and logic in separate projectsViewModels in a separate class libraryViewModels in the same project referencing Avalonia typesMyApp.Core (no Avalonia refs) + MyApp.Desktop (Avalonia views)ViewModel importing Avalonia.ControlsMediumhttps://docs.avaloniaui.net/docs/how-to/mvvm-how-toavalonia 12active2026-08-13
3130AccessibilitySet AutomationPropertiesEnable screen reader supportAutomationProperties.Name on interactive controlsControls without accessible names<Button AutomationProperties.Name="Close dialog"><PathIcon Data="..."/></Button><Button><PathIcon/></Button> without accessible nameHighhttps://docs.avaloniaui.net/api/avalonia/automation/automationpropertiesavalonia 12active2026-08-13
3231AccessibilitySupport keyboard navigationFull keyboard operabilityTabIndex and KeyboardNavigation propertiesMouse-only interactions<Button TabIndex="1" Content="Save"/>Clickable controls without keyboard supportHighhttps://docs.avaloniaui.net/docs/input-interaction/keyboard-and-hotkeysavalonia 12active2026-08-13
3332AccessibilityUse semantic control typesControls convey meaning to assistive techButton for actions ListBox for selectionTextBlock with PointerPressed as fake button<Button Content="Submit"/><TextBlock PointerPressed="OnSubmitClick" Text="Submit"/>Highhttps://docs.avaloniaui.net/docs/reference/controls/avalonia 12active2026-08-13
3433TestingUse Avalonia.Headless for UI testsRun UI tests without display serverAvalonia.Headless for CI-compatible UI testingSkipping UI tests in CI[AvaloniaTest] public void Button_Click_Updates_Label() { ... }UI tests that require a display serverMediumhttps://docs.avaloniaui.net/docs/concepts/headless/avalonia 12active2026-08-13
3534TestingUnit test ViewModelsTest business logic independentlyxUnit or NUnit on ViewModel methodsTesting through UI only[Fact] public void AddItem_IncreasesCount() { vm.AddItem(); Assert.Equal(1, vm.Items.Count); }Manual testing by running the appMediumhttps://docs.avaloniaui.net/docs/concepts/headless/avalonia 12active2026-08-13
3635TestingTest converters independentlyValue converters contain testable logicUnit tests on Convert and ConvertBackAssuming converters work without tests[Fact] public void BoolToColor_True_ReturnsGreen() { Assert.Equal(Brushes.Green, converter.Convert(true)); }No converter testsLowhttps://docs.avaloniaui.net/docs/data-binding/how-to-create-a-custom-data-binding-converteravalonia 12active2026-08-13
3736NavigationUse ReactiveUI routing for navigationIScreen and RoutingState for page navigationReactiveUI RoutingState with IScreen on main ViewModelManual content swapping in code-behindpublic RoutingState Router { get; } = new(); Router.Navigate.Execute(new DetailViewModel());contentControl.Content = new DetailView(); in code-behindMediumhttps://docs.avaloniaui.net/docs/how-to/navigation-how-toavalonia 12active2026-08-13
3837NavigationUse UserControl for viewsPages and screens should be UserControls hosted in a ContentControlUserControl for each view with RoutedViewHost or ContentControlWindow per page or nested Windows<UserControl x:Class="MyApp.Views.DetailView">new Window() for each page in the appMediumhttps://docs.avaloniaui.net/docs/custom-controls/avalonia 12active2026-08-13
3938NavigationUse page transitions for view switchingBuilt-in transitions for smooth navigationCrossFade PageSlide or CompositePageTransition declared as a property elementAbrupt content swaps with no visual continuity<RoutedViewHost><RoutedViewHost.PageTransition><PageSlide Orientation="Horizontal" Duration="0:0:0.3"/></RoutedViewHost.PageTransition></RoutedViewHost>ContentControl with no transition between viewsLowhttps://docs.avaloniaui.net/docs/reference/controls/transitioningcontentcontrolavalonia 12active2026-08-13
4039NavigationSupport back navigationMaintain navigation history for complex appsRouter.NavigateBack or custom back stackNo way to return to previous views<Button Command="{Binding Router.NavigateBack}" Content="Back"/>Single-direction navigation with no back supportMediumhttps://docs.avaloniaui.net/docs/how-to/navigation-how-toavalonia 12active2026-08-13
4140ControlsUse AutoCompleteBox for searchBuilt-in autocomplete and suggestion controlAutoCompleteBox with FilterMode and ItemsSourceTextBox with manual Popup and ListBox for suggestions<AutoCompleteBox ItemsSource="{Binding Suggestions}" FilterMode="Contains"/>TextBox with custom Popup for autocompleteMediumhttps://docs.avaloniaui.net/docs/reference/controls/autocompleteboxavalonia 12active2026-08-13
4241ControlsUse TabControl for tabbed interfacesStandard tabbed navigation and content switchingTabControl with TabItem for tabbed layoutsManual toggle buttons swapping content<TabControl><TabItem Header="General"><GeneralView/></TabItem><TabItem Header="Advanced"><AdvancedView/></TabItem></TabControl>ToggleButtons with manual content switching logicMediumhttps://docs.avaloniaui.net/docs/reference/controls/tabcontrolavalonia 12active2026-08-13
4342ControlsUse SplitView for master-detailCollapsible pane layout for navigation or panelsSplitView with Pane and Content areasManual Grid with column toggling for sidebar<SplitView IsPaneOpen="{Binding IsPaneOpen}" DisplayMode="Inline"><SplitView.Pane><ListBox/></SplitView.Pane><ContentControl/></SplitView>Grid with manual column width animation for sidebarMediumhttps://docs.avaloniaui.net/docs/reference/controls/splitviewavalonia 12active2026-08-13
4443ControlsUse Flyout for contextual actionsAttach popup menus and actions to controlsFlyout and MenuFlyout on Button or other controlsCustom Popup positioning and management<Button Content="Options"><Button.Flyout><MenuFlyout><MenuItem Header="Edit"/><MenuItem Header="Delete"/></MenuFlyout></Button.Flyout></Button>Custom Popup with manual open/close and positioningMediumhttps://docs.avaloniaui.net/docs/reference/controls/flyoutsavalonia 12active2026-08-13
4544LifecycleUse AppBuilder for app configurationConfigure platform features and services at startupAppBuilder with UsePlatformDetect and fluent APIManual platform initializationAppBuilder.Configure<App>().UsePlatformDetect().WithInterFont().StartWithClassicDesktopLifetime(args);Manual platform-specific startup code per OSHighhttps://docs.avaloniaui.net/docs/fundamentals/application-lifetimesavalonia 12active2026-08-13
4645LifecycleInitialize MainWindow in OnFrameworkInitializationCompletedOverride OnFrameworkInitializationCompleted on App and check ApplicationLifetime - on desktop cast to IClassicDesktopStyleApplicationLifetime to set MainWindow and ShutdownMode; never create windows in the App constructor before the framework is readyOverride OnFrameworkInitializationCompleted and pattern-match on IClassicDesktopStyleApplicationLifetime for desktop-only setupCreating windows in the App constructor or assuming the same lifetime type on every platformpublic override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { desktop.MainWindow = new MainWindow(); desktop.ShutdownMode = ShutdownMode.OnMainWindowClose; } base.OnFrameworkInitializationCompleted(); }public App() { new MainWindow().Show(); } // window created before framework init and ignores lifetime typeHighhttps://docs.avaloniaui.net/docs/fundamentals/application-lifetimesavalonia 12active2026-08-13
4746AnimationUse CSS-like keyframe animationsAvalonia supports declarative animations in XAML and codeAnimation with KeyFrame and Setter for property animationsManual timer-based property updates<Border.Transitions><DoubleTransition Property="Opacity" Duration="0:0:0.3"/></Border.Transitions>DispatcherTimer ticking to update Opacity manuallyMediumhttps://docs.avaloniaui.net/docs/graphics-animation/animationsavalonia 12active2026-08-13
4847AnimationUse Transitions for implicit animationsAutomatic animation when property values changeTransitions collection on controls for smooth changesInstant property changes with no visual feedback<Button.Transitions><TransformOperationsTransition Property="RenderTransform" Duration="0:0:0.2"/></Button.Transitions>Direct property set with no transitionLowhttps://docs.avaloniaui.net/docs/graphics-animation/control-transitionsavalonia 12active2026-08-13
4948PerformanceUse compiled bindings and TrimmerRoots.xml for PublishAotAvalonia 11+ supports Native AOT for self-contained desktop deployments; XAML reflection paths must use compiled bindings or be preserved via TrimmerRoots so trimming does not strip themx:CompileBindings=True on every view plus TrimmerRoots.xml for runtime-resolved typesPublishAot with reflection-based {Binding} markup or trimming without checking warnings<UserControl x:CompileBindings="True" x:DataType="vm:MainViewModel"/> with <PublishAot>true</PublishAot> and TrimmerRoots.xml listing reflected types<PublishAot>true</PublishAot> with default <Binding> markup and no TrimmerRoots configurationMediumhttps://docs.avaloniaui.net/docs/deployment/native-aotavalonia 12active2026-08-13
5049ThreadingMarshal cross-thread work to the UI threadAvalonia controls and bound properties are not thread-safe and touching them off the UI thread throws InvalidOperationExceptionDispatcher.UIThread.Post or InvokeAsync to bounce work back to the UI threadDirect property writes from Task.Run or background threadsawait Dispatcher.UIThread.InvokeAsync(() => Status = "Done");Task.Run(() => { Status = "Done"; }); // throws Call from invalid threadHighhttps://docs.avaloniaui.net/docs/app-development/threadingavalonia 12active2026-08-13
5150CommandsUse AsyncRelayCommand or ReactiveCommand for async workAsync-aware commands disable themselves while running and surface CancellationToken so users cannot double-invoke a long operation[RelayCommand] async Task method or ReactiveCommand.CreateFromTaskasync void event handlers or fire-and-forget Task.Run from a click handler[RelayCommand] private async Task LoadAsync(CancellationToken ct) { await _api.GetAsync(ct); }private async void OnClick(object s, RoutedEventArgs e) { await LongOperation(); }Highhttps://docs.avaloniaui.net/docs/input-interaction/commandingavalonia 12active2026-08-13
5251StylingUse DynamicResource for theme-aware brushesResourceDictionary.ThemeDictionaries entries must be looked up via DynamicResource - StaticResource resolves once at load and won't update when the active theme variant changesDynamicResource for brushes and colors that follow the active theme variantHardcoded hex colors or StaticResource for values that should follow theme<Border Background="{DynamicResource SystemControlBackgroundAccentBrush}"/><Border Background="#FF0078D4"/> while the rest of the app honors light/dark variantsMediumhttps://docs.avaloniaui.net/docs/app-development/resource-dictionaryavalonia 12active2026-08-13
5352InputUse HotKey or KeyBinding for keyboard shortcutsBuilt-in HotKey on ICommandSource and Window.KeyBindings handle modifier keys focus scoping and cross-platform Ctrl/Cmd mappingHotKey on a command-bound control or KeyBinding on the WindowManual KeyDown handlers checking Key and KeyModifiers<Button Command="{Binding SaveCommand}" HotKey="Ctrl+S" Content="Save"/>OnKeyDown checking e.Key == Key.S && e.KeyModifiers == KeyModifiers.ControlMediumhttps://docs.avaloniaui.net/docs/input-interaction/mouse-and-keyboard-shortcutsavalonia 12active2026-08-13
5453WindowingCustomize window chrome with ExtendClientAreaToDecorationsHintSet ExtendClientAreaToDecorationsHint to extend content into the title bar area and tag a region with WindowDecorationProperties.ElementRole=TitleBar to keep native drag and maximize behaviorExtendClientAreaToDecorationsHint plus a region tagged ElementRole=TitleBarSystemDecorations=None with hand-rolled PointerPressed dragging in code-behind<Window ExtendClientAreaToDecorationsHint="True"><Border WindowDecorationProperties.ElementRole="TitleBar"/></Window><Window SystemDecorations="None"> with manual BeginMoveDrag from code-behindMediumhttps://docs.avaloniaui.net/docs/app-development/window-managementavalonia 12active2026-08-13
5554StorageUse TopLevel.StorageProvider for file pickersThe legacy OpenFileDialog/SaveFileDialog APIs are obsolete - use TopLevel.GetTopLevel(this).StorageProvider with OpenFilePickerAsync/SaveFilePickerAsync/OpenFolderPickerAsync which returns IStorageFile/IStorageFolder and works on desktop mobile and browserTopLevel.StorageProvider with OpenFilePickerAsync and FilePickerOpenOptionsOpenFileDialog or SaveFileDialog from older Avalonia samples or copied from WPFvar top = TopLevel.GetTopLevel(this); var files = await top.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions { AllowMultiple = false });var dlg = new OpenFileDialog(); var paths = await dlg.ShowAsync(window); // obsolete APIHighhttps://docs.avaloniaui.net/docs/services/storage/storage-provideravalonia 12active2026-08-13
5655WindowingUse TrayIcon for system tray iconTrayIcon shows a native system tray/notification-area icon with a NativeMenu - declare it via the Application.TrayIcon.Icons attached property in App.axaml; works on Windows macOS and most Linux desktopsTrayIcon with NativeMenu inside TrayIcon.Icons on the ApplicationCustom borderless window pretending to be a tray icon or per-platform native interop<TrayIcon.Icons><TrayIcons><TrayIcon Icon="/Assets/tray.ico" ToolTipText="MyApp"><TrayIcon.Menu><NativeMenu><NativeMenuItem Header="Show" Command="{Binding ShowCommand}"/></NativeMenu></TrayIcon.Menu></TrayIcon></TrayIcons></TrayIcon.Icons>Hidden Window with custom shell-notification-area P/InvokeMediumhttps://docs.avaloniaui.net/docs/controls/tray-iconavalonia 12active2026-08-13
5756Cross-PlatformUse OnPlatform and OnFormFactor markup for per-OS valuesOnPlatform and OnFormFactor markup extensions resolve to a different value per OS or form factor at XAML load time and replace if-statements in code-behind for tweaks like fonts spacing or icon sizesOnPlatform with Default Windows macOS Linux entries directly in the property setterRuntimeInformation.IsOSPlatform branches in code-behind to set XAML properties<TextBlock FontFamily="{OnPlatform Default='Inter', Windows='Segoe UI', macOS='SF Pro Text', Linux='Ubuntu'}"/>if (OperatingSystem.IsWindows()) textBlock.FontFamily = new("Segoe UI"); else if (OperatingSystem.IsMacOS()) ...Mediumhttps://docs.avaloniaui.net/docs/platform-specific-guides/xamlavalonia 12active2026-08-13