feat(stacks): add 5 .NET desktop stacks — WPF, WinUI 3, UWP, Avalonia, Uno Platform

Adds WPF, WinUI 3, UWP, Avalonia, and Uno Platform stacks (17 -> 22 total),
each with its own guidelines CSV, registered in core.py and synced to cli/assets.

- New stack CSVs in src/ and cli/assets/data/stacks/
- search.py / core.py registry updated
- smoke-stacks.sh: EXPECTED_STACK_COUNT 21 -> 22 with a smoke-test workflow
- platform template descriptions and README bumped to 22 technology stacks
This commit is contained in:
Jan Ivar Z. Carlsen
2026-06-25 21:51:59 +02:00
parent 318e0b2e40
commit 090a405cc0
32 changed files with 707 additions and 27 deletions

28
.github/workflows/smoke-stacks.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
name: Smoke test stacks
on:
pull_request:
paths:
- 'src/ui-ux-pro-max/data/stacks/**'
- 'src/ui-ux-pro-max/scripts/**'
- 'cli/assets/data/stacks/**'
- 'cli/assets/scripts/**'
- 'scripts/smoke-stacks.sh'
- '.github/workflows/smoke-stacks.yml'
push:
branches: [main]
workflow_dispatch:
jobs:
smoke:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Run stack smoke test
run: bash scripts/smoke-stacks.sh

View File

@@ -154,7 +154,7 @@ Each rule includes:
- **161 Color Palettes** - Industry-specific palettes aligned 1:1 with the 161 product types
- **57 Font Pairings** - Curated typography combinations with Google Fonts imports
- **25 Chart Types** - Recommendations for dashboards and analytics
- **17 Tech Stacks** - React, Next.js, Astro, Vue, Nuxt.js, Nuxt UI, Svelte, SwiftUI, React Native, Flutter, HTML+Tailwind, shadcn/ui, Jetpack Compose, Angular, Laravel, Three.js, JavaFX
- **22 Tech Stacks** - React, Next.js, Astro, Vue, Nuxt.js, Nuxt UI, Svelte, SwiftUI, React Native, Flutter, HTML+Tailwind, shadcn/ui, Jetpack Compose, Angular, Laravel, Three.js, JavaFX, WPF, WinUI 3, UWP, Avalonia, Uno Platform
- **99 UX Guidelines** - Best practices, anti-patterns, and accessibility rules
- **161 Reasoning Rules** - Industry-specific design system generation (NEW in v2.0)

View File

@@ -0,0 +1,57 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,XAML,Use Avalonia XAML namespace,Avalonia has its own XAML namespace not WPF,xmlns= for Avalonia-specific namespace,WPF xmlns or UWP xmlns,"<Window xmlns=""https://github.com/avaloniaui"">","<Window xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">",High,https://docs.avaloniaui.net/docs/fundamentals/avalonia-xaml
2,XAML,Use compiled bindings with x:DataType,Enable compile-time binding validation,x:DataType on root or DataTemplate for compiled bindings,Reflection-based bindings in production,"<Window x:DataType=""vm:MainViewModel""><TextBlock Text=""{Binding Name}""/></Window>","<Window><TextBlock Text=""{Binding Name}""/> without x:DataType",High,https://docs.avaloniaui.net/docs/data-binding/compiled-bindings
3,XAML,Enable compiled bindings globally,AvaloniaUseCompiledBindingsByDefault in csproj makes every binding require x:DataType and is required for trim-safe Native AOT,AvaloniaUseCompiledBindingsByDefault MSBuild property in csproj,Relying on runtime binding resolution,"<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>","No compiled binding enforcement",High,https://docs.avaloniaui.net/docs/data-binding/compiled-bindings
4,XAML,Use #name shorthand for element-to-element bindings,Compiled bindings cannot resolve {Binding ElementName=...} - use the #name shorthand which relies on NameScope lookup,#name shorthand referencing x:Name controls in the same NameScope,ElementName binding inside a compiled-binding scope,"<TextBlock Text=""{Binding #SearchBox.Text}""/>","<TextBlock Text=""{Binding ElementName=SearchBox, Path=Text}""/> under compiled bindings",Medium,https://docs.avaloniaui.net/docs/data-binding/compiled-bindings
5,Styling,Use CSS-like selectors,Avalonia uses selectors not implicit styles,Selectors targeting control types classes and pseudoclasses,WPF-style implicit Style with TargetType,"<Style Selector=""Button.primary""><Setter Property=""Background"" Value=""Blue""/></Style>","<Style TargetType=""Button""> without Selector",High,https://docs.avaloniaui.net/docs/styling/selectors
6,Styling,Use pseudoclass selectors for states,Target control states with colon syntax,:pointerover :pressed :focus for interactive states,VisualStateManager or Triggers,"<Style Selector=""Button:pointerover""><Setter Property=""Opacity"" Value=""0.8""/></Style>","<VisualStateManager> for hover effects",Medium,https://docs.avaloniaui.net/docs/styling/pseudoclasses
7,Styling,Use nesting selectors,Child and descendant combinators for scoped styles,> for direct child and space for descendant,Flat selectors that match too broadly,"<Style Selector=""StackPanel > Button""><Setter Property=""Margin"" Value=""4""/></Style>","<Style Selector=""Button""> that affects all buttons unintentionally",Medium,https://docs.avaloniaui.net/docs/styling/style-selector-syntax
8,Styling,Use StyleInclude for modularity,Split styles into separate AXAML files,StyleInclude to import themed resource files,All styles in a single monolithic App.axaml,"<StyleInclude Source=""/Styles/ButtonStyles.axaml""/>","1000+ line App.axaml with all styles",Medium,https://docs.avaloniaui.net/docs/styling/styles
9,Styling,Use Fluent or Simple theme,Built-in Avalonia themes,FluentTheme or SimpleTheme as base,Custom theme from scratch,"<FluentTheme/>","Building all control templates manually",High,https://docs.avaloniaui.net/docs/styling/themes
10,Styling,Use theme variants for dark mode,Switch between light and dark,RequestedThemeVariant for theme switching,"Hardcoded colors ignoring theme variants","Application.Current.RequestedThemeVariant = ThemeVariant.Dark;","Manually changing every brush for dark mode",Medium,https://docs.avaloniaui.net/docs/styling/themes
11,Controls,Use DataGrid for tabular data,DataGrid is a separate Avalonia.Controls.DataGrid NuGet package and requires its theme StyleInclude in App.axaml,DataGrid after adding package and StyleInclude for the matching theme,Custom 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)",Medium,https://docs.avaloniaui.net/docs/reference/controls/datagrid/
12,Controls,Use TreeView with TreeDataTemplate,Avalonia uses TreeDataTemplate for hierarchical data - HierarchicalDataTemplate is WPF only,TreeDataTemplate inside TreeView.ItemTemplate with ItemsSource pointing at child collection,HierarchicalDataTemplate 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 Avalonia",High,https://docs.avaloniaui.net/docs/reference/controls/treeview-1
13,Controls,Use NativeMenu for platform menus,Native menu bar on macOS and desktop,NativeMenu for cross-platform menu bar,Custom menu implementation per platform,"<NativeMenu.Menu><NativeMenu><NativeMenuItem Header=""File""/></NativeMenu></NativeMenu.Menu>","Custom menu bar control for each platform",Medium,https://docs.avaloniaui.net/docs/reference/controls/nativemenu
14,Data Binding,Implement INotifyPropertyChanged,Standard .NET property notification,INotifyPropertyChanged or CommunityToolkit.Mvvm,Properties without change notification,"[ObservableProperty] private string _name;","public string Name { get; set; } without notification",High,https://docs.avaloniaui.net/docs/data-binding/inotifypropertychanged
15,Data Binding,Use ObservableCollection for lists,UI updates on collection changes,ObservableCollection<T> for bound collections,List<T> for ItemsSources,"ObservableCollection<Item> Items { get; } = new();","List<Item> Items { get; set; }",High,https://docs.avaloniaui.net/docs/data-binding/inotifypropertychanged
16,Data Binding,Use binding to named controls,Element-to-element binding with # syntax,#ElementName.Property for cross-element binding,Code-behind for element references,"<TextBlock Text=""{Binding #slider.Value, StringFormat='{}{0:F0}'}""/>","Code-behind ValueChanged handler to update TextBlock",Medium,https://docs.avaloniaui.net/docs/data-binding/introduction-to-data-binding
17,Data Binding,Use converters or FuncValueConverter,Transform data for display,FuncValueConverter for simple inline conversions,Complex IValueConverter classes for trivial transforms,"public static FuncValueConverter<bool, IBrush> BoolToColor = new(b => b ? Brushes.Green : Brushes.Red);","Full IValueConverter class for bool to color",Medium,https://docs.avaloniaui.net/docs/data-binding/how-to-create-a-custom-data-binding-converter
18,Cross-Platform,Use platform-specific code carefully,Isolate platform code behind abstractions,Interface + platform implementation pattern,#if directives scattered through ViewModels,"IPlatformService with platform-specific implementations","#if WINDOWS ... #elif LINUX ... in ViewModel",Medium,https://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/
19,Cross-Platform,Test on all target platforms,Rendering and behavior varies across platforms,CI testing on Windows macOS and Linux,Testing only on development platform,"GitHub Actions matrix with windows-latest ubuntu-latest macos-latest","Testing only on Windows assuming cross-platform works",High,https://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/
20,Cross-Platform,Handle platform file paths,Path separators differ across OS,Path.Combine and Environment.SpecialFolder,Hardcoded backslashes or forward slashes,"Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), ""MyApp"")","@""C:\Users\data\config.json""",Medium,https://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/dealing-with-platforms
21,Cross-Platform,Use Avalonia asset system,Platform-agnostic resource loading,avares:// URI scheme for embedded resources,File system paths for assets,"<Image Source=""avares://MyApp/Assets/logo.png""/>","<Image Source=""C:/images/logo.png""/>",High,https://docs.avaloniaui.net/docs/fundamentals/including-assets
22,Performance,Use virtualization for large lists,Only render visible items,ListBox and ItemsRepeater with virtualization,Non-virtualizing ItemsControl for large lists,"<ListBox ItemsSource=""{Binding LargeList}""/>","<ItemsControl><StackPanel> for 10K items",High,https://docs.avaloniaui.net/docs/reference/controls/listbox
23,Performance,Avoid unnecessary bindings,Each binding has overhead,Bind only properties that change,Binding static labels and headers,"<TextBlock Text=""{Binding DynamicTitle}""/> but static: <TextBlock Text=""Settings""/>","<TextBlock Text=""{Binding SettingsLabel}""/> for constant string",Low,https://docs.avaloniaui.net/docs/data-binding/introduction-to-data-binding
24,Performance,Set bitmap interpolation mode on scaled images,RenderOptions.BitmapInterpolationMode controls image scaling quality vs cost; default may look aliased on upscaled or downscaled bitmaps,RenderOptions.SetBitmapInterpolationMode tuned to the use case,Default interpolation on scaled images that look blurry or aliased,"RenderOptions.SetBitmapInterpolationMode(image, BitmapInterpolationMode.HighQuality);","Image scaled with Stretch and no interpolation hint set",Low,https://docs.avaloniaui.net/docs/concepts/image-interpolation
25,Performance,Profile with Avalonia DevTools,Built-in diagnostic tools,DevTools for visual tree and binding inspection,Console.WriteLine debugging,Attach DevTools in debug mode with F12,Print statements to debug layout issues,Medium,https://docs.avaloniaui.net/docs/guides/implementation-guides/developer-tools
26,Architecture,Use MVVM with ReactiveUI or CommunityToolkit,Proven MVVM frameworks for Avalonia,ReactiveUI or CommunityToolkit.Mvvm for ViewModels,Code-behind for all logic,"public class MainViewModel : ReactiveObject { }","MainWindow.axaml.cs with all business logic",High,https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/
27,Architecture,Use ViewLocator pattern,Convention-based View-ViewModel resolution,ViewLocator for automatic view resolution,Manual view instantiation and DataContext wiring,"class ViewLocator : IDataTemplate { Build(object data) => new MainView(); }","new MainView { DataContext = new MainViewModel() } everywhere",Medium,https://docs.avaloniaui.net/docs/data-templates/view-locator
28,Architecture,Use dependency injection,Register services in a Microsoft.Extensions.DependencyInjection container during startup before any view is constructed - resolve ViewModels through the provider not via a static ServiceLocator,Build the ServiceProvider in BuildAvaloniaApp or OnFrameworkInitializationCompleted then resolve ViewModels from it,Static ServiceLocator or new-ing ViewModels inline in code-behind,"services.AddSingleton<IDataService, DataService>(); services.AddTransient<MainViewModel>(); var provider = services.BuildServiceProvider(); // wired before windows are created","ServiceLocator.Current.GetInstance<IDataService>() called from random ViewModels with no registration ordering",Medium,https://docs.avaloniaui.net/docs/app-development/dependency-injection
29,Architecture,Separate Views from ViewModels,Keep UI and logic in separate projects,ViewModels in a separate class library,ViewModels in the same project referencing Avalonia types,"MyApp.Core (no Avalonia refs) + MyApp.Desktop (Avalonia views)","ViewModel importing Avalonia.Controls",Medium,https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/
30,Accessibility,Set AutomationProperties,Enable screen reader support,AutomationProperties.Name on interactive controls,Controls without accessible names,"<Button AutomationProperties.Name=""Close dialog""><PathIcon Data=""...""/></Button>","<Button><PathIcon/></Button> without accessible name",High,https://docs.avaloniaui.net/api/avalonia/automation/automationproperties
31,Accessibility,Support keyboard navigation,Full keyboard operability,TabIndex and KeyboardNavigation properties,Mouse-only interactions,"<Button TabIndex=""1"" Content=""Save""/>","Clickable controls without keyboard support",High,https://docs.avaloniaui.net/docs/input-interaction/keyboard-and-hotkeys
32,Accessibility,Use semantic control types,Controls convey meaning to assistive tech,Button for actions ListBox for selection,TextBlock with PointerPressed as fake button,"<Button Content=""Submit""/>","<TextBlock PointerPressed=""OnSubmitClick"" Text=""Submit""/>",High,https://docs.avaloniaui.net/docs/reference/controls/
33,Testing,Use Avalonia.Headless for UI tests,Run UI tests without display server,Avalonia.Headless for CI-compatible UI testing,Skipping UI tests in CI,"[AvaloniaTest] public void Button_Click_Updates_Label() { ... }","UI tests that require a display server",Medium,https://docs.avaloniaui.net/docs/concepts/headless/
34,Testing,Unit test ViewModels,Test business logic independently,xUnit or NUnit on ViewModel methods,Testing through UI only,"[Fact] public void AddItem_IncreasesCount() { vm.AddItem(); Assert.Equal(1, vm.Items.Count); }","Manual testing by running the app",Medium,https://docs.avaloniaui.net/docs/concepts/headless/
35,Testing,Test converters independently,Value converters contain testable logic,Unit tests on Convert and ConvertBack,Assuming converters work without tests,"[Fact] public void BoolToColor_True_ReturnsGreen() { Assert.Equal(Brushes.Green, converter.Convert(true)); }","No converter tests",Low,https://docs.avaloniaui.net/docs/data-binding/how-to-create-a-custom-data-binding-converter
36,Navigation,Use ReactiveUI routing for navigation,IScreen and RoutingState for page navigation,ReactiveUI RoutingState with IScreen on main ViewModel,Manual content swapping in code-behind,"public RoutingState Router { get; } = new(); Router.Navigate.Execute(new DetailViewModel());","contentControl.Content = new DetailView(); in code-behind",Medium,https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/routing
37,Navigation,Use UserControl for views,Pages and screens should be UserControls hosted in a ContentControl,UserControl for each view with RoutedViewHost or ContentControl,Window per page or nested Windows,"<UserControl x:Class=""MyApp.Views.DetailView"">","new Window() for each page in the app",Medium,https://docs.avaloniaui.net/docs/custom-controls/
38,Navigation,Use page transitions for view switching,Built-in transitions for smooth navigation,CrossFade PageSlide or CompositePageTransition declared as a property element,Abrupt 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 views",Low,https://docs.avaloniaui.net/docs/reference/controls/transitioningcontentcontrol
39,Navigation,Support back navigation,Maintain navigation history for complex apps,Router.NavigateBack or custom back stack,No way to return to previous views,"<Button Command=""{Binding Router.NavigateBack}"" Content=""Back""/>","Single-direction navigation with no back support",Medium,https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/routing
40,Controls,Use AutoCompleteBox for search,Built-in autocomplete and suggestion control,AutoCompleteBox with FilterMode and ItemsSource,TextBox with manual Popup and ListBox for suggestions,"<AutoCompleteBox ItemsSource=""{Binding Suggestions}"" FilterMode=""Contains""/>","TextBox with custom Popup for autocomplete",Medium,https://docs.avaloniaui.net/docs/reference/controls/autocompletebox
41,Controls,Use TabControl for tabbed interfaces,Standard tabbed navigation and content switching,TabControl with TabItem for tabbed layouts,Manual toggle buttons swapping content,"<TabControl><TabItem Header=""General""><GeneralView/></TabItem><TabItem Header=""Advanced""><AdvancedView/></TabItem></TabControl>","ToggleButtons with manual content switching logic",Medium,https://docs.avaloniaui.net/docs/reference/controls/tabcontrol
42,Controls,Use SplitView for master-detail,Collapsible pane layout for navigation or panels,SplitView with Pane and Content areas,Manual 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 sidebar",Medium,https://docs.avaloniaui.net/docs/reference/controls/splitview
43,Controls,Use Flyout for contextual actions,Attach popup menus and actions to controls,Flyout and MenuFlyout on Button or other controls,Custom 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 positioning",Medium,https://docs.avaloniaui.net/docs/reference/controls/flyouts
44,Lifecycle,Use AppBuilder for app configuration,Configure platform features and services at startup,AppBuilder with UsePlatformDetect and fluent API,Manual platform initialization,"AppBuilder.Configure<App>().UsePlatformDetect().WithInterFont().StartWithClassicDesktopLifetime(args);","Manual platform-specific startup code per OS",High,https://docs.avaloniaui.net/docs/fundamentals/application-lifetimes
45,Lifecycle,Initialize MainWindow in OnFrameworkInitializationCompleted,Override 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 ready,Override OnFrameworkInitializationCompleted and pattern-match on IClassicDesktopStyleApplicationLifetime for desktop-only setup,Creating windows in the App constructor or assuming the same lifetime type on every platform,"public 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 type",High,https://docs.avaloniaui.net/docs/fundamentals/application-lifetimes
46,Animation,Use CSS-like keyframe animations,Avalonia supports declarative animations in XAML and code,Animation with KeyFrame and Setter for property animations,Manual timer-based property updates,"<Border.Transitions><DoubleTransition Property=""Opacity"" Duration=""0:0:0.3""/></Border.Transitions>","DispatcherTimer ticking to update Opacity manually",Medium,https://docs.avaloniaui.net/docs/graphics-animation/animations
47,Animation,Use Transitions for implicit animations,Automatic animation when property values change,Transitions collection on controls for smooth changes,Instant property changes with no visual feedback,"<Button.Transitions><TransformOperationsTransition Property=""RenderTransform"" Duration=""0:0:0.2""/></Button.Transitions>","Direct property set with no transition",Low,https://docs.avaloniaui.net/docs/graphics-animation/control-transitions
48,Performance,Use compiled bindings and TrimmerRoots.xml for PublishAot,Avalonia 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 them,x:CompileBindings=True on every view plus TrimmerRoots.xml for runtime-resolved types,PublishAot 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 configuration",Medium,https://docs.avaloniaui.net/docs/deployment/native-aot
49,Threading,Marshal cross-thread work to the UI thread,Avalonia controls and bound properties are not thread-safe and touching them off the UI thread throws InvalidOperationException,Dispatcher.UIThread.Post or InvokeAsync to bounce work back to the UI thread,Direct property writes from Task.Run or background threads,"await Dispatcher.UIThread.InvokeAsync(() => Status = ""Done"");","Task.Run(() => { Status = ""Done""; }); // throws Call from invalid thread",High,https://docs.avaloniaui.net/docs/app-development/threading
50,Commands,Use AsyncRelayCommand or ReactiveCommand for async work,Async-aware commands disable themselves while running and surface CancellationToken so users cannot double-invoke a long operation,[RelayCommand] async Task method or ReactiveCommand.CreateFromTask,async 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(); }",High,https://docs.avaloniaui.net/docs/input-interaction/commanding
51,Styling,Use DynamicResource for theme-aware brushes,ResourceDictionary.ThemeDictionaries entries must be looked up via DynamicResource - StaticResource resolves once at load and won't update when the active theme variant changes,DynamicResource for brushes and colors that follow the active theme variant,Hardcoded 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 variants",Medium,https://docs.avaloniaui.net/docs/app-development/resource-dictionary
52,Input,Use HotKey or KeyBinding for keyboard shortcuts,Built-in HotKey on ICommandSource and Window.KeyBindings handle modifier keys focus scoping and cross-platform Ctrl/Cmd mapping,HotKey on a command-bound control or KeyBinding on the Window,Manual KeyDown handlers checking Key and KeyModifiers,"<Button Command=""{Binding SaveCommand}"" HotKey=""Ctrl+S"" Content=""Save""/>","OnKeyDown checking e.Key == Key.S && e.KeyModifiers == KeyModifiers.Control",Medium,https://docs.avaloniaui.net/docs/input-interaction/mouse-and-keyboard-shortcuts
53,Windowing,Customize window chrome with ExtendClientAreaToDecorationsHint,Set ExtendClientAreaToDecorationsHint to extend content into the title bar area and tag a region with WindowDecorationProperties.ElementRole=TitleBar to keep native drag and maximize behavior,ExtendClientAreaToDecorationsHint plus a region tagged ElementRole=TitleBar,SystemDecorations=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-behind",Medium,https://docs.avaloniaui.net/docs/app-development/window-management
54,Storage,Use TopLevel.StorageProvider for file pickers,The legacy OpenFileDialog/SaveFileDialog APIs are obsolete in Avalonia 11 - use TopLevel.GetTopLevel(this).StorageProvider with OpenFilePickerAsync/SaveFilePickerAsync/OpenFolderPickerAsync which returns IStorageFile/IStorageFolder and works on desktop mobile and browser,TopLevel.StorageProvider with OpenFilePickerAsync and FilePickerOpenOptions,OpenFileDialog or SaveFileDialog from older Avalonia samples or copied from WPF,"var 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 API",High,https://docs.avaloniaui.net/docs/concepts/services/storage-provider/
55,Windowing,Use TrayIcon for system tray icon,TrayIcon 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 desktops,TrayIcon with NativeMenu inside TrayIcon.Icons on the Application,Custom 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/Invoke",Medium,https://docs.avaloniaui.net/docs/controls/tray-icon
56,Cross-Platform,Use OnPlatform and OnFormFactor markup for per-OS values,OnPlatform 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 sizes,OnPlatform with Default Windows macOS Linux entries directly in the property setter,RuntimeInformation.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()) ...",Medium,https://docs.avaloniaui.net/docs/platform-specific-guides/xaml
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 XAML Use Avalonia XAML namespace Avalonia has its own XAML namespace not WPF xmlns= for Avalonia-specific namespace WPF xmlns or UWP xmlns <Window xmlns="https://github.com/avaloniaui"> <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> High https://docs.avaloniaui.net/docs/fundamentals/avalonia-xaml
3 2 XAML Use compiled bindings with x:DataType Enable compile-time binding validation x:DataType on root or DataTemplate for compiled bindings Reflection-based bindings in production <Window x:DataType="vm:MainViewModel"><TextBlock Text="{Binding Name}"/></Window> <Window><TextBlock Text="{Binding Name}"/> without x:DataType High https://docs.avaloniaui.net/docs/data-binding/compiled-bindings
4 3 XAML Enable compiled bindings globally AvaloniaUseCompiledBindingsByDefault in csproj makes every binding require x:DataType and is required for trim-safe Native AOT AvaloniaUseCompiledBindingsByDefault MSBuild property in csproj Relying on runtime binding resolution <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault> No compiled binding enforcement High https://docs.avaloniaui.net/docs/data-binding/compiled-bindings
5 4 XAML Use #name shorthand for element-to-element bindings Compiled bindings cannot resolve {Binding ElementName=...} - use the #name shorthand which relies on NameScope lookup #name shorthand referencing x:Name controls in the same NameScope ElementName binding inside a compiled-binding scope <TextBlock Text="{Binding #SearchBox.Text}"/> <TextBlock Text="{Binding ElementName=SearchBox, Path=Text}"/> under compiled bindings Medium https://docs.avaloniaui.net/docs/data-binding/compiled-bindings
6 5 Styling Use CSS-like selectors Avalonia uses selectors not implicit styles Selectors targeting control types classes and pseudoclasses WPF-style implicit Style with TargetType <Style Selector="Button.primary"><Setter Property="Background" Value="Blue"/></Style> <Style TargetType="Button"> without Selector High https://docs.avaloniaui.net/docs/styling/selectors
7 6 Styling Use pseudoclass selectors for states Target control states with colon syntax :pointerover :pressed :focus for interactive states VisualStateManager or Triggers <Style Selector="Button:pointerover"><Setter Property="Opacity" Value="0.8"/></Style> <VisualStateManager> for hover effects Medium https://docs.avaloniaui.net/docs/styling/pseudoclasses
8 7 Styling Use nesting selectors Child and descendant combinators for scoped styles > for direct child and space for descendant Flat selectors that match too broadly <Style Selector="StackPanel > Button"><Setter Property="Margin" Value="4"/></Style> <Style Selector="Button"> that affects all buttons unintentionally Medium https://docs.avaloniaui.net/docs/styling/style-selector-syntax
9 8 Styling Use StyleInclude for modularity Split styles into separate AXAML files StyleInclude to import themed resource files All styles in a single monolithic App.axaml <StyleInclude Source="/Styles/ButtonStyles.axaml"/> 1000+ line App.axaml with all styles Medium https://docs.avaloniaui.net/docs/styling/styles
10 9 Styling Use Fluent or Simple theme Built-in Avalonia themes FluentTheme or SimpleTheme as base Custom theme from scratch <FluentTheme/> Building all control templates manually High https://docs.avaloniaui.net/docs/styling/themes
11 10 Styling Use theme variants for dark mode Switch between light and dark RequestedThemeVariant for theme switching Hardcoded colors ignoring theme variants Application.Current.RequestedThemeVariant = ThemeVariant.Dark; Manually changing every brush for dark mode Medium https://docs.avaloniaui.net/docs/styling/themes
12 11 Controls Use DataGrid for tabular data DataGrid is a separate Avalonia.Controls.DataGrid NuGet package and requires its theme StyleInclude in App.axaml DataGrid after adding package and StyleInclude for the matching theme Custom 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) Medium https://docs.avaloniaui.net/docs/reference/controls/datagrid/
13 12 Controls Use TreeView with TreeDataTemplate Avalonia uses TreeDataTemplate for hierarchical data - HierarchicalDataTemplate is WPF only TreeDataTemplate inside TreeView.ItemTemplate with ItemsSource pointing at child collection HierarchicalDataTemplate 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 Avalonia High https://docs.avaloniaui.net/docs/reference/controls/treeview-1
14 13 Controls Use NativeMenu for platform menus Native menu bar on macOS and desktop NativeMenu for cross-platform menu bar Custom menu implementation per platform <NativeMenu.Menu><NativeMenu><NativeMenuItem Header="File"/></NativeMenu></NativeMenu.Menu> Custom menu bar control for each platform Medium https://docs.avaloniaui.net/docs/reference/controls/nativemenu
15 14 Data Binding Implement INotifyPropertyChanged Standard .NET property notification INotifyPropertyChanged or CommunityToolkit.Mvvm Properties without change notification [ObservableProperty] private string _name; public string Name { get; set; } without notification High https://docs.avaloniaui.net/docs/data-binding/inotifypropertychanged
16 15 Data Binding Use ObservableCollection for lists UI updates on collection changes ObservableCollection<T> for bound collections List<T> for ItemsSources ObservableCollection<Item> Items { get; } = new(); List<Item> Items { get; set; } High https://docs.avaloniaui.net/docs/data-binding/inotifypropertychanged
17 16 Data Binding Use binding to named controls Element-to-element binding with # syntax #ElementName.Property for cross-element binding Code-behind for element references <TextBlock Text="{Binding #slider.Value, StringFormat='{}{0:F0}'}"/> Code-behind ValueChanged handler to update TextBlock Medium https://docs.avaloniaui.net/docs/data-binding/introduction-to-data-binding
18 17 Data Binding Use converters or FuncValueConverter Transform data for display FuncValueConverter for simple inline conversions Complex IValueConverter classes for trivial transforms public static FuncValueConverter<bool, IBrush> BoolToColor = new(b => b ? Brushes.Green : Brushes.Red); Full IValueConverter class for bool to color Medium https://docs.avaloniaui.net/docs/data-binding/how-to-create-a-custom-data-binding-converter
19 18 Cross-Platform Use platform-specific code carefully Isolate platform code behind abstractions Interface + platform implementation pattern #if directives scattered through ViewModels IPlatformService with platform-specific implementations #if WINDOWS ... #elif LINUX ... in ViewModel Medium https://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/
20 19 Cross-Platform Test on all target platforms Rendering and behavior varies across platforms CI testing on Windows macOS and Linux Testing only on development platform GitHub Actions matrix with windows-latest ubuntu-latest macos-latest Testing only on Windows assuming cross-platform works High https://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/
21 20 Cross-Platform Handle platform file paths Path separators differ across OS Path.Combine and Environment.SpecialFolder Hardcoded backslashes or forward slashes Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MyApp") @"C:\Users\data\config.json" Medium https://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/dealing-with-platforms
22 21 Cross-Platform Use Avalonia asset system Platform-agnostic resource loading avares:// URI scheme for embedded resources File system paths for assets <Image Source="avares://MyApp/Assets/logo.png"/> <Image Source="C:/images/logo.png"/> High https://docs.avaloniaui.net/docs/fundamentals/including-assets
23 22 Performance Use virtualization for large lists Only render visible items ListBox and ItemsRepeater with virtualization Non-virtualizing ItemsControl for large lists <ListBox ItemsSource="{Binding LargeList}"/> <ItemsControl><StackPanel> for 10K items High https://docs.avaloniaui.net/docs/reference/controls/listbox
24 23 Performance Avoid unnecessary bindings Each binding has overhead Bind only properties that change Binding static labels and headers <TextBlock Text="{Binding DynamicTitle}"/> but static: <TextBlock Text="Settings"/> <TextBlock Text="{Binding SettingsLabel}"/> for constant string Low https://docs.avaloniaui.net/docs/data-binding/introduction-to-data-binding
25 24 Performance Set bitmap interpolation mode on scaled images RenderOptions.BitmapInterpolationMode controls image scaling quality vs cost; default may look aliased on upscaled or downscaled bitmaps RenderOptions.SetBitmapInterpolationMode tuned to the use case Default interpolation on scaled images that look blurry or aliased RenderOptions.SetBitmapInterpolationMode(image, BitmapInterpolationMode.HighQuality); Image scaled with Stretch and no interpolation hint set Low https://docs.avaloniaui.net/docs/concepts/image-interpolation
26 25 Performance Profile with Avalonia DevTools Built-in diagnostic tools DevTools for visual tree and binding inspection Console.WriteLine debugging Attach DevTools in debug mode with F12 Print statements to debug layout issues Medium https://docs.avaloniaui.net/docs/guides/implementation-guides/developer-tools
27 26 Architecture Use MVVM with ReactiveUI or CommunityToolkit Proven MVVM frameworks for Avalonia ReactiveUI or CommunityToolkit.Mvvm for ViewModels Code-behind for all logic public class MainViewModel : ReactiveObject { } MainWindow.axaml.cs with all business logic High https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/
28 27 Architecture Use ViewLocator pattern Convention-based View-ViewModel resolution ViewLocator for automatic view resolution Manual view instantiation and DataContext wiring class ViewLocator : IDataTemplate { Build(object data) => new MainView(); } new MainView { DataContext = new MainViewModel() } everywhere Medium https://docs.avaloniaui.net/docs/data-templates/view-locator
29 28 Architecture Use dependency injection Register services in a Microsoft.Extensions.DependencyInjection container during startup before any view is constructed - resolve ViewModels through the provider not via a static ServiceLocator Build the ServiceProvider in BuildAvaloniaApp or OnFrameworkInitializationCompleted then resolve ViewModels from it Static ServiceLocator or new-ing ViewModels inline in code-behind services.AddSingleton<IDataService, DataService>(); services.AddTransient<MainViewModel>(); var provider = services.BuildServiceProvider(); // wired before windows are created ServiceLocator.Current.GetInstance<IDataService>() called from random ViewModels with no registration ordering Medium https://docs.avaloniaui.net/docs/app-development/dependency-injection
30 29 Architecture Separate Views from ViewModels Keep UI and logic in separate projects ViewModels in a separate class library ViewModels in the same project referencing Avalonia types MyApp.Core (no Avalonia refs) + MyApp.Desktop (Avalonia views) ViewModel importing Avalonia.Controls Medium https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/
31 30 Accessibility Set AutomationProperties Enable screen reader support AutomationProperties.Name on interactive controls Controls without accessible names <Button AutomationProperties.Name="Close dialog"><PathIcon Data="..."/></Button> <Button><PathIcon/></Button> without accessible name High https://docs.avaloniaui.net/api/avalonia/automation/automationproperties
32 31 Accessibility Support keyboard navigation Full keyboard operability TabIndex and KeyboardNavigation properties Mouse-only interactions <Button TabIndex="1" Content="Save"/> Clickable controls without keyboard support High https://docs.avaloniaui.net/docs/input-interaction/keyboard-and-hotkeys
33 32 Accessibility Use semantic control types Controls convey meaning to assistive tech Button for actions ListBox for selection TextBlock with PointerPressed as fake button <Button Content="Submit"/> <TextBlock PointerPressed="OnSubmitClick" Text="Submit"/> High https://docs.avaloniaui.net/docs/reference/controls/
34 33 Testing Use Avalonia.Headless for UI tests Run UI tests without display server Avalonia.Headless for CI-compatible UI testing Skipping UI tests in CI [AvaloniaTest] public void Button_Click_Updates_Label() { ... } UI tests that require a display server Medium https://docs.avaloniaui.net/docs/concepts/headless/
35 34 Testing Unit test ViewModels Test business logic independently xUnit or NUnit on ViewModel methods Testing through UI only [Fact] public void AddItem_IncreasesCount() { vm.AddItem(); Assert.Equal(1, vm.Items.Count); } Manual testing by running the app Medium https://docs.avaloniaui.net/docs/concepts/headless/
36 35 Testing Test converters independently Value converters contain testable logic Unit tests on Convert and ConvertBack Assuming converters work without tests [Fact] public void BoolToColor_True_ReturnsGreen() { Assert.Equal(Brushes.Green, converter.Convert(true)); } No converter tests Low https://docs.avaloniaui.net/docs/data-binding/how-to-create-a-custom-data-binding-converter
37 36 Navigation Use ReactiveUI routing for navigation IScreen and RoutingState for page navigation ReactiveUI RoutingState with IScreen on main ViewModel Manual content swapping in code-behind public RoutingState Router { get; } = new(); Router.Navigate.Execute(new DetailViewModel()); contentControl.Content = new DetailView(); in code-behind Medium https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/routing
38 37 Navigation Use UserControl for views Pages and screens should be UserControls hosted in a ContentControl UserControl for each view with RoutedViewHost or ContentControl Window per page or nested Windows <UserControl x:Class="MyApp.Views.DetailView"> new Window() for each page in the app Medium https://docs.avaloniaui.net/docs/custom-controls/
39 38 Navigation Use page transitions for view switching Built-in transitions for smooth navigation CrossFade PageSlide or CompositePageTransition declared as a property element Abrupt 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 views Low https://docs.avaloniaui.net/docs/reference/controls/transitioningcontentcontrol
40 39 Navigation Support back navigation Maintain navigation history for complex apps Router.NavigateBack or custom back stack No way to return to previous views <Button Command="{Binding Router.NavigateBack}" Content="Back"/> Single-direction navigation with no back support Medium https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/routing
41 40 Controls Use AutoCompleteBox for search Built-in autocomplete and suggestion control AutoCompleteBox with FilterMode and ItemsSource TextBox with manual Popup and ListBox for suggestions <AutoCompleteBox ItemsSource="{Binding Suggestions}" FilterMode="Contains"/> TextBox with custom Popup for autocomplete Medium https://docs.avaloniaui.net/docs/reference/controls/autocompletebox
42 41 Controls Use TabControl for tabbed interfaces Standard tabbed navigation and content switching TabControl with TabItem for tabbed layouts Manual toggle buttons swapping content <TabControl><TabItem Header="General"><GeneralView/></TabItem><TabItem Header="Advanced"><AdvancedView/></TabItem></TabControl> ToggleButtons with manual content switching logic Medium https://docs.avaloniaui.net/docs/reference/controls/tabcontrol
43 42 Controls Use SplitView for master-detail Collapsible pane layout for navigation or panels SplitView with Pane and Content areas Manual 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 sidebar Medium https://docs.avaloniaui.net/docs/reference/controls/splitview
44 43 Controls Use Flyout for contextual actions Attach popup menus and actions to controls Flyout and MenuFlyout on Button or other controls Custom 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 positioning Medium https://docs.avaloniaui.net/docs/reference/controls/flyouts
45 44 Lifecycle Use AppBuilder for app configuration Configure platform features and services at startup AppBuilder with UsePlatformDetect and fluent API Manual platform initialization AppBuilder.Configure<App>().UsePlatformDetect().WithInterFont().StartWithClassicDesktopLifetime(args); Manual platform-specific startup code per OS High https://docs.avaloniaui.net/docs/fundamentals/application-lifetimes
46 45 Lifecycle Initialize MainWindow in OnFrameworkInitializationCompleted Override 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 ready Override OnFrameworkInitializationCompleted and pattern-match on IClassicDesktopStyleApplicationLifetime for desktop-only setup Creating windows in the App constructor or assuming the same lifetime type on every platform public 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 type High https://docs.avaloniaui.net/docs/fundamentals/application-lifetimes
47 46 Animation Use CSS-like keyframe animations Avalonia supports declarative animations in XAML and code Animation with KeyFrame and Setter for property animations Manual timer-based property updates <Border.Transitions><DoubleTransition Property="Opacity" Duration="0:0:0.3"/></Border.Transitions> DispatcherTimer ticking to update Opacity manually Medium https://docs.avaloniaui.net/docs/graphics-animation/animations
48 47 Animation Use Transitions for implicit animations Automatic animation when property values change Transitions collection on controls for smooth changes Instant property changes with no visual feedback <Button.Transitions><TransformOperationsTransition Property="RenderTransform" Duration="0:0:0.2"/></Button.Transitions> Direct property set with no transition Low https://docs.avaloniaui.net/docs/graphics-animation/control-transitions
49 48 Performance Use compiled bindings and TrimmerRoots.xml for PublishAot Avalonia 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 them x:CompileBindings=True on every view plus TrimmerRoots.xml for runtime-resolved types PublishAot 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 configuration Medium https://docs.avaloniaui.net/docs/deployment/native-aot
50 49 Threading Marshal cross-thread work to the UI thread Avalonia controls and bound properties are not thread-safe and touching them off the UI thread throws InvalidOperationException Dispatcher.UIThread.Post or InvokeAsync to bounce work back to the UI thread Direct property writes from Task.Run or background threads await Dispatcher.UIThread.InvokeAsync(() => Status = "Done"); Task.Run(() => { Status = "Done"; }); // throws Call from invalid thread High https://docs.avaloniaui.net/docs/app-development/threading
51 50 Commands Use AsyncRelayCommand or ReactiveCommand for async work Async-aware commands disable themselves while running and surface CancellationToken so users cannot double-invoke a long operation [RelayCommand] async Task method or ReactiveCommand.CreateFromTask async 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(); } High https://docs.avaloniaui.net/docs/input-interaction/commanding
52 51 Styling Use DynamicResource for theme-aware brushes ResourceDictionary.ThemeDictionaries entries must be looked up via DynamicResource - StaticResource resolves once at load and won't update when the active theme variant changes DynamicResource for brushes and colors that follow the active theme variant Hardcoded 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 variants Medium https://docs.avaloniaui.net/docs/app-development/resource-dictionary
53 52 Input Use HotKey or KeyBinding for keyboard shortcuts Built-in HotKey on ICommandSource and Window.KeyBindings handle modifier keys focus scoping and cross-platform Ctrl/Cmd mapping HotKey on a command-bound control or KeyBinding on the Window Manual KeyDown handlers checking Key and KeyModifiers <Button Command="{Binding SaveCommand}" HotKey="Ctrl+S" Content="Save"/> OnKeyDown checking e.Key == Key.S && e.KeyModifiers == KeyModifiers.Control Medium https://docs.avaloniaui.net/docs/input-interaction/mouse-and-keyboard-shortcuts
54 53 Windowing Customize window chrome with ExtendClientAreaToDecorationsHint Set ExtendClientAreaToDecorationsHint to extend content into the title bar area and tag a region with WindowDecorationProperties.ElementRole=TitleBar to keep native drag and maximize behavior ExtendClientAreaToDecorationsHint plus a region tagged ElementRole=TitleBar SystemDecorations=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-behind Medium https://docs.avaloniaui.net/docs/app-development/window-management
55 54 Storage Use TopLevel.StorageProvider for file pickers The legacy OpenFileDialog/SaveFileDialog APIs are obsolete in Avalonia 11 - use TopLevel.GetTopLevel(this).StorageProvider with OpenFilePickerAsync/SaveFilePickerAsync/OpenFolderPickerAsync which returns IStorageFile/IStorageFolder and works on desktop mobile and browser TopLevel.StorageProvider with OpenFilePickerAsync and FilePickerOpenOptions OpenFileDialog or SaveFileDialog from older Avalonia samples or copied from WPF var 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 API High https://docs.avaloniaui.net/docs/concepts/services/storage-provider/
56 55 Windowing Use TrayIcon for system tray icon TrayIcon 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 desktops TrayIcon with NativeMenu inside TrayIcon.Icons on the Application Custom 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/Invoke Medium https://docs.avaloniaui.net/docs/controls/tray-icon
57 56 Cross-Platform Use OnPlatform and OnFormFactor markup for per-OS values OnPlatform 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 sizes OnPlatform with Default Windows macOS Linux entries directly in the property setter RuntimeInformation.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()) ... Medium https://docs.avaloniaui.net/docs/platform-specific-guides/xaml

View File

@@ -0,0 +1,60 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,XAML,Use WinUI XAML API surface,Uno implements the WinUI API across platforms,Microsoft.UI.Xaml namespace for all UI code,WPF or Xamarin.Forms namespaces,"using Microsoft.UI.Xaml.Controls;","using System.Windows.Controls; or using Xamarin.Forms;",High,https://platform.uno/docs/articles/implemented-views.html
2,XAML,Check API implementation status,Not all WinUI APIs are implemented on every platform,Uno API compatibility docs before using new APIs,Assuming all WinUI APIs work everywhere,"Check platform.uno/docs for API status","Using unimplemented API and discovering at runtime",High,https://platform.uno/docs/articles/implemented-views.html
3,XAML,Use Uno.WinUI not Uno.UI for new projects,Uno.WinUI uses WinUI 3 APIs,Uno.WinUI NuGet packages for new projects,Uno.UI (UWP API surface) for new projects,"<Project Sdk=""Uno.Sdk""> (Uno.WinUI / WinUI 3 surface implicit)","<PackageReference Include=""Uno.UI""/> (legacy UWP API surface)",Medium,https://platform.uno/docs/articles/updating-to-winui3.html
4,XAML,Use XAML Hot Reload,Speed up development with live XAML editing,Hot Reload for iterating on layouts,Restarting app for every XAML change,"Click Hot Reload button in VS toolbar or save in VS Code/Rider to apply XAML changes","Full rebuild for margin tweak",Medium,https://platform.uno/docs/articles/features/working-with-xaml-hot-reload.html
5,Conditional,Use platform-specific XAML,Conditional namespaces for platform-specific UI,xmlns:android xmlns:ios xmlns:wasm for platform XAML,Shared XAML when platforms need different controls,"<TextBlock android:Text=""Android"" ios:Text=""iOS"" Text=""Default""/>","#if in code-behind to set text per platform",Medium,https://platform.uno/docs/articles/platform-specific-xaml.html
6,Conditional,Use partial classes for platform code,Separate platform implementations in partial files,Partial class files with platform-specific logic,#if directives in shared code for large blocks,"MainPage.iOS.cs MainPage.Android.cs partial class files","#if __IOS__ ... #elif __ANDROID__ ... 100-line blocks in shared file",Medium,https://platform.uno/docs/articles/platform-specific-csharp.html
7,Conditional,Use preprocessor symbols correctly,Target correct platforms with defines,__IOS__ __ANDROID__ __WASM__ __DESKTOP__ for platform checks,Inventing custom symbols or checking OS at runtime,"#if __ANDROID__ Android-specific code #endif","if (RuntimeInformation.IsOSPlatform(OSPlatform.Android)) for compile-time choice",Medium,https://platform.uno/docs/articles/platform-specific-csharp.html
8,Conditional,Minimize platform-specific code,Keep shared code maximized,Abstract platform differences behind interfaces,Duplicating logic across platform files,"IDeviceService with per-platform implementation","Same 50 lines copy-pasted into iOS and Android partial classes",High,https://platform.uno/docs/articles/platform-specific-csharp.html
9,Navigation,Use Frame-based navigation,Standard WinUI navigation pattern,Frame.Navigate with page types,Manual content swapping,"rootFrame.Navigate(typeof(DetailPage), parameter);","contentPresenter.Content = new DetailPage();",Medium,https://platform.uno/docs/articles/guides/native-frame-nav-tutorial.html
10,Navigation,Use Uno.Extensions.Navigation,Type-safe navigation with DI integration,Uno.Extensions navigation for complex apps,Manual Frame management in large apps,"navigator.NavigateViewModelAsync<DetailViewModel>(this, data: item);","Frame.Navigate with string parsing everywhere",Medium,https://platform.uno/docs/articles/external/uno.extensions/doc/Overview/Navigation/NavigationOverview.html
11,Navigation,Handle platform back navigation,SystemNavigationManager.BackRequested works on Android iOS and WASM but is unimplemented on WinAppSDK desktop where calling GetForCurrentView() throws at runtime,Subscribe to BackRequested only on platforms that support it or use Uno.Toolkit NavigationBar for cross-platform back UX,Calling SystemNavigationManager.GetForCurrentView() on WinUI 3 desktop without a guard,"#if __ANDROID__ || __IOS__ || __WASM__ SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested; #endif","SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested; with no platform guard — crashes on Windows desktop",High,https://platform.uno/docs/articles/guides/native-frame-nav-tutorial.html
12,Navigation,Use deep linking,Support URI activation across platforms,Handle protocol activation and URI routing,Single entry point ignoring activation,Route URIs to specific pages on activation,Ignoring OnLaunched activation args,Medium,https://platform.uno/docs/articles/features/protocol-activation.html
13,Renderers,Understand Skia vs native rendering,Uno offers both rendering approaches,Skia for pixel-perfect cross-platform consistency,Assuming native rendering on all platforms,"<TargetFrameworks>net10.0-desktop;net10.0-browserwasm</TargetFrameworks> uses unified Skia Desktop shell","Expecting platform-native controls on Skia targets",High,https://platform.uno/docs/articles/features/using-skia-desktop.html
14,Renderers,Use unified net10.0-desktop target,Uno 5.2+ ships a single Skia Desktop shell that auto-selects X11 Win32 or AppKit per OS — Skia.Gtk Skia.Linux.Framebuffer and Skia.WPF heads are deprecated,net10.0-desktop TFM with UnoPlatformHostBuilder for cross-platform desktop,Targeting the legacy Skia.Gtk or Skia.Linux.Framebuffer heads in new projects,"<TargetFrameworks>net10.0-desktop</TargetFrameworks> in the Uno.Sdk single project","Per-OS Skia.Gtk Skia.MacOS Skia.Linux.Framebuffer head projects",Medium,https://platform.uno/docs/articles/features/using-skia-desktop.html
15,Renderers,Test rendering on each target,Visual differences exist between renderers,Visual testing on each active target platform,Testing only on Windows assuming others match,"Screenshot tests on iOS Android WASM and Desktop","Testing only on Windows Desktop",High,https://platform.uno/docs/articles/external/uno.uitest/doc/using-uno-uitest.html
16,Renderers,Use platform-native features when needed,Access native APIs through Uno abstractions,Native platform APIs via platform-specific code,Avoiding native features for purity,"#if __IOS__ UIKit API call #endif for camera access","Pure shared code that avoids using the camera",Medium,https://platform.uno/docs/articles/platform-specific-csharp.html
17,Performance,Optimize WASM bundle size,WebAssembly downloads can be large,IL linker and AOT for smaller WASM bundles,Default settings for production WASM,"<WasmShellILLinkerEnabled>true</WasmShellILLinkerEnabled>","Publishing WASM without linker",High,https://platform.uno/docs/articles/features/using-il-linker-webassembly.html
18,Performance,Use x:Load for deferred XAML,Defer element creation until needed,x:Load=False for hidden panels and tabs,Loading all UI elements upfront,"<StackPanel x:Load=""{x:Bind ShowAdvanced}"">","Always-loaded Collapsed panels",Medium,https://platform.uno/docs/articles/features/windows-ui-xaml-xbind.html
19,Data Binding,Use x:Bind for compiled bindings,Compiled bindings eliminate runtime reflection — Uno supports x:Bind across iOS Android WASM Skia and Windows targets that compile XAML so prefer it over {Binding} for static well-typed bindings,x:Bind for property and event bindings; reserve {Binding} for runtime-typed DataContext scenarios,{Binding} everywhere when x:Bind would compile,"<TextBlock Text=""{x:Bind ViewModel.Title, Mode=OneWay}""/>","<TextBlock Text=""{Binding Title}""/> for a statically known property",High,https://platform.uno/docs/articles/features/windows-ui-xaml-xbind.html
20,Performance,Profile per platform,Performance characteristics vary by target,Platform-specific profiling tools,Assuming desktop perf equals mobile,"Instruments on iOS and Android Profiler on Android","Profiling only on Windows",Medium,https://platform.uno/docs/articles/guides/profiling-applications.html
21,Styling,Use WinUI theme resources,Consistent theming across platforms,ThemeResource for adaptive colors,Hardcoded colors per platform,"Background=""{ThemeResource ApplicationPageBackgroundThemeBrush}""","Background=""#FFFFFF""",High,https://platform.uno/docs/articles/features/working-with-themes.html
22,Styling,Support light and dark themes,Application.RequestedTheme accepts only ApplicationTheme.Light/Dark — to follow the system theme leave it unset entirely. ElementTheme.Default exists only on FrameworkElement.RequestedTheme not on Application,Omit Application.RequestedTheme so the OS theme wins; use RequestedTheme=Default on FrameworkElement to inherit from parent,Setting Application.RequestedTheme=""Default"" — not a valid ApplicationTheme value and throws at parse time,"<Application></Application> with RequestedTheme unset; <Grid RequestedTheme=""Default"">...</Grid> on a FrameworkElement","<Application RequestedTheme=""Default""> // not a valid ApplicationTheme",Medium,https://platform.uno/docs/articles/features/working-with-themes.html
23,Styling,Use Lightweight Styling,Override control sub-properties via resources,Lightweight styling keys for minor tweaks,Full ControlTemplate for small changes,"<Button><Button.Resources><StaticResource x:Key=""ButtonBackground"" ResourceKey=""AccentBrush""/></Button.Resources></Button>","Copying entire ControlTemplate to change one color",Medium,https://platform.uno/docs/articles/external/uno.themes/doc/lightweight-styling.html
24,Styling,Test themes on each platform,Theme rendering differs across platforms,Visual theme testing on all targets,Assuming themes look identical everywhere,"Screenshot comparison across platforms for themed controls","Theming only tested on Windows",Low,https://platform.uno/docs/articles/features/working-with-themes.html
25,Architecture,Use MVVM pattern,Separate view and logic,CommunityToolkit.Mvvm or Prism for MVVM,Code-behind for business logic,"[ObservableProperty] public partial string Title { get; set; } [RelayCommand] private void Save() { }","MainPage.xaml.cs with all logic",High,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
26,Architecture,Use Uno.Extensions,Official extension libraries for common patterns,Uno.Extensions for DI navigation configuration,Building infrastructure from scratch,"Host.CreateDefaultBuilder().UseNavigation().UseConfiguration()","Manual DI and navigation setup",Medium,https://platform.uno/docs/articles/external/uno.extensions/doc/ExtensionsOverview.html
27,Architecture,Use dependency injection,Register services for testability,Microsoft.Extensions.DI through Uno.Extensions,Static service locators and singletons,"services.AddSingleton<IApiService, ApiService>();","ApiService.Instance or new ApiService() in ViewModels",Medium,https://platform.uno/docs/articles/external/uno.extensions/doc/Learn/DependencyInjection/DependencyInjectionOverview.html
28,Architecture,Share code via class libraries,Maximize code reuse across targets,Business logic in .NET Standard or shared library,Business logic in platform head projects,"MyApp.Core class library referenced by all heads","Business logic in MyApp.Wasm.csproj",Medium,https://platform.uno/docs/articles/cross-targeted-libraries.html
29,Architecture,Use Uno.Resizetizer for assets,Single source SVG to multi-platform assets,UnoImage for automatic asset generation from SVG,Manual asset export per resolution and platform,"<UnoImage Include=""Assets/icon.svg"" BaseSize=""24,24""/>","Manually exporting icon_1x.png icon_2x.png icon_3x.png per platform",Medium,https://platform.uno/docs/articles/external/uno.resizetizer/doc/using-uno-resizetizer.html
30,Accessibility,Set AutomationProperties,Enable screen readers across platforms,AutomationProperties.Name on interactive controls,Controls without accessible names,"<Button AutomationProperties.Name=""Submit form""><SymbolIcon Symbol=""Accept""/></Button>","<Button><SymbolIcon Symbol=""Accept""/></Button> without name",High,https://platform.uno/docs/articles/features/working-with-accessibility.html
31,Accessibility,Test accessibility per platform,Each platform has different assistive tech,Test with VoiceOver TalkBack and Narrator,Testing accessibility on one platform only,"VoiceOver on iOS + TalkBack on Android + Narrator on Windows","Only testing with Narrator on Windows",High,https://platform.uno/docs/articles/features/working-with-accessibility.html
32,Accessibility,Support platform text scaling,Respect user font size preferences,Dynamic font scaling for all text,Fixed font sizes ignoring accessibility,"FontSize=""{ThemeResource BodyTextBlockFontSize}""","FontSize=""14"" everywhere",Medium,https://platform.uno/docs/articles/features/working-with-accessibility.html
33,Testing,Unit test ViewModels,Test business logic independently,xUnit or MSTest on shared ViewModel code,UI testing only,"[Fact] public void LoadData_SetsItems() { vm.Load(); Assert.NotEmpty(vm.Items); }","Manual testing on each platform",Medium,https://platform.uno/docs/articles/external/uno.uitest/doc/using-uno-uitest.html
34,Testing,Use Uno.UITest for integration,Cross-platform UI testing framework,Uno.UITest for automated UI tests across platforms,Manual regression testing,"app.WaitForElement(""SaveButton""); app.Tap(""SaveButton"");","Manual click-through on each platform",Medium,https://platform.uno/docs/articles/external/uno.uitest/doc/using-uno-uitest.html
35,WASM,Show an extended splash screen on WASM,WASM bundle download and runtime startup take several seconds on first load — render branded UI immediately so users do not see a blank page (AOT and trimming are covered separately),Render a splash overlay in wwwroot/index.html that hides on first XAML navigation,Letting the user wait on a blank white page while the runtime boots,"index.html: <div id=""uno-loading"">Loading…</div> hidden via JS interop after first Frame.Navigate","No splash markup in index.html — 5-second blank page on first visit",Medium,https://platform.uno/docs/articles/external/uno.wasm.bootstrap/doc/runtime-execution-modes.html
36,WASM,Use AOT compilation for performance,Ahead-of-time compilation improves runtime speed,AOT for production WASM builds,Interpreter mode in production,"<WasmShellMonoRuntimeExecutionMode>InterpreterAndAOT</WasmShellMonoRuntimeExecutionMode>","Default interpreter mode in production deployment",Medium,https://platform.uno/docs/articles/external/uno.wasm.bootstrap/doc/runtime-execution-modes.html
37,WASM,Handle browser limitations,WASM runs in browser sandbox,Feature detection for browser APIs,Assuming desktop capabilities in browser,"[JSImport(""globalThis.hasApi"")] static partial bool HasApi(); #if __WASM__ if (HasApi()) { ... } #endif","#if __WASM__ StorageFile.GetFileFromPathAsync(""C:/data"") #endif",Medium,https://platform.uno/docs/articles/platform-specific-csharp.html
38,Controls,Use NavigationView for app shell,WinUI NavigationView for consistent navigation across platforms,NavigationView with MenuItems for app navigation,Custom hamburger menu implementation,"<NavigationView><NavigationView.MenuItems><NavigationViewItem Content=""Home"" Icon=""Home""/></NavigationView.MenuItems></NavigationView>","Custom SplitView with manual toggle button",High,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/navigationview
39,Controls,Use ContentDialog for modal interactions,Cross-platform modal dialogs using WinUI API,ContentDialog for confirmations and input,Custom overlay Panel as dialog,"<ContentDialog Title=""Confirm"" PrimaryButtonText=""OK"" CloseButtonText=""Cancel""/>","Grid overlay with manual focus trapping",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/dialogs-and-flyouts/dialogs
40,Controls,Use CommandBar for app actions,Standard command bar with primary and secondary commands,CommandBar with AppBarButtons for toolbar actions,Custom StackPanel toolbar,"<CommandBar><AppBarButton Icon=""Save"" Label=""Save""/><AppBarButton Icon=""Delete"" Label=""Delete""/></CommandBar>","<StackPanel Orientation=""Horizontal""><Button>Save</Button></StackPanel>",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/command-bar
41,Controls,Use ToggleSwitch for boolean settings,Platform-native toggle control for on/off preferences,ToggleSwitch for settings and feature flags,CheckBox for toggle settings,"<ToggleSwitch Header=""Dark Mode"" IsOn=""{x:Bind ViewModel.IsDarkMode, Mode=TwoWay}""/>","<CheckBox Content=""Enable dark mode""/>",Low,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/toggles
42,Data Binding,Implement INotifyPropertyChanged,Enable UI updates when ViewModel properties change,CommunityToolkit.Mvvm [ObservableProperty] for auto-notification,Properties without change notification,"[ObservableProperty] public partial string Title { get; set; }","public string Title { get; set; } without notification",High,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
43,Data Binding,Use ObservableCollection for bound lists,Collection change notifications for ItemsSources across platforms,ObservableCollection<T> for data-bound lists,List<T> for bound ItemsSources,"ObservableCollection<Item> Items { get; } = new();","List<Item> Items { get; set; } = new();",High,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
44,Lifecycle,Handle app suspension on mobile,iOS and Android may suspend or terminate the app — WinAppSDK desktop does not raise Suspending so use window Closed for desktop save-state,Save state in OnSuspending and restore on activation,Ignoring lifecycle losing user state on mobile,"Application.Current.Suspending += (s, e) => { var d = e.SuspendingOperation.GetDeferral(); SaveState(); d.Complete(); };","No suspend handler losing form data on mobile",High,https://platform.uno/docs/articles/features/windows-ui-xaml-application.html
45,Lifecycle,Use Uno.Extensions.Hosting for startup,Structured app initialization with DI and configuration,IHost builder pattern for app startup and service registration,Manual initialization in App constructor,"Host.CreateDefaultBuilder().ConfigureServices(s => s.AddSingleton<MainViewModel>()).Build();","new MainViewModel() in App.xaml.cs constructor",Medium,https://platform.uno/docs/articles/external/uno.extensions/doc/Overview/Hosting/HostingOverview.html
46,Performance,Use ListView virtualization for large lists,Only renders visible items to reduce memory and layout cost,ListView with default ItemsStackPanel virtualization,ItemsControl or StackPanel for large data sets,"<ListView ItemsSource=""{x:Bind Items}""/> (virtualizes by default)","<ItemsControl><StackPanel> rendering 5000 items at once",High,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/listview-and-gridview
47,Accessibility,Support keyboard navigation on desktop,Skia and WinAppSDK targets need full keyboard operability — note TabIndex routing is not fully implemented on every Uno target,AccessKey and KeyboardAccelerator on Skia and WinAppSDK targets,Mouse-only interactions on desktop,"<Button AccessKey=""S"" Content=""Save""><Button.KeyboardAccelerators><KeyboardAccelerator Modifiers=""Control"" Key=""S""/></Button.KeyboardAccelerators></Button>","Clickable controls without keyboard support on desktop",High,https://learn.microsoft.com/en-us/windows/apps/develop/input/keyboard-accelerators
48,WASM,Use service workers for offline support,Enable PWA capabilities for WASM deployments,Service worker registration for caching and offline mode,Online-only WASM app with no offline fallback,"<WasmPWAManifestFile>manifest.webmanifest</WasmPWAManifestFile>","No service worker leaving WASM app unusable offline",Low,https://platform.uno/docs/articles/external/uno.wasm.bootstrap/doc/features-pwa.html
49,Performance,Marshal to UI thread with DispatcherQueue,Cross-thread access to UI elements throws — capture the UI DispatcherQueue once and use TryEnqueue to update from background work,DispatcherQueue.GetForCurrentThread().TryEnqueue from background work,Touching UI controls directly from a Task,"_dispatcher.TryEnqueue(() => StatusText.Text = ""Done"");","await Task.Run(() => StatusText.Text = ""Done""); throws on non-UI thread",High,https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.dispatching.dispatcherqueue
50,Styling,Merge XamlControlsResources in App.xaml,Required for Fluent control styles to load — without it controls render with no template,Add XamlControlsResources at the top of Application.Resources MergedDictionaries,Skipping the merged dictionary and wondering why Buttons look unstyled,"<Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><XamlControlsResources xmlns=""using:Microsoft.UI.Xaml.Controls""/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources>","<Application.Resources><SolidColorBrush x:Key=""MyBrush"" Color=""Red""/></Application.Resources> with no XamlControlsResources merged",High,https://platform.uno/docs/articles/features/fluent-styles.html
51,Architecture,Use async [RelayCommand] for I/O,AsyncRelayCommand reports CanExecute=false (raising CanExecuteChanged) and exposes IsRunning while the Task is in flight — the bound control is disabled and re-entrancy is prevented by default (AllowConcurrentExecutions=false),[RelayCommand] on a Task-returning method for awaitable work,async void event handlers calling .Wait() or .Result,"[RelayCommand] private async Task LoadAsync() { Items = await _api.GetAsync(); }","public void OnLoadClick(object s, EventArgs e) { LoadAsync().Wait(); } deadlock risk",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/generators/relaycommand
52,Architecture,Use x:Uid for localized strings,WinUI x:Uid resolves UI text from .resw resources at runtime — use it instead of hardcoded strings to support localization across iOS Android WASM and desktop from a single project,x:Uid on every user-facing string with matching .resw entries per language under Strings/{lang}/Resources.resw,Hardcoding language-specific strings into XAML or code-behind,"<Button x:Uid=""SubmitButton""/> with Strings/en/Resources.resw entry SubmitButton.Content=Submit","<Button Content=""Submit""/> hardcoded in XAML",High,https://platform.uno/docs/articles/features/working-with-strings.html
53,Architecture,Wire up ILogger via Uno.Extensions.Logging,Cross-platform logging routes to platform-native sinks (OSLog on iOS Console on WASM Debug elsewhere) when configured through the IHost builder,Inject ILogger<T> into ViewModels and services and call UseLogging() on the host builder,Console.WriteLine or platform-specific log APIs scattered across shared code,"Host.CreateDefaultBuilder().UseLogging(c => c.SetMinimumLevel(LogLevel.Information)) and ILogger<MainViewModel> via constructor injection","Console.WriteLine(""error"") in shared code with no platform-aware routing",Medium,https://platform.uno/docs/articles/external/uno.extensions/doc/Overview/Logging/LoggingOverview.html
54,Performance,Enable PublishAot on net10.0-desktop,Skia Desktop on .NET 10 supports Native AOT for faster cold start and smaller deployments — opt in per-target so debug builds remain fast,<PublishAot>true</PublishAot> in a TFM-conditional PropertyGroup for net10.0-desktop release builds,Enabling PublishAot globally and breaking debug iteration on every TFM,"<PropertyGroup Condition=""'$(TargetFramework)'=='net10.0-desktop' AND '$(Configuration)'=='Release'""><PublishAot>true</PublishAot></PropertyGroup>","<PublishAot>true</PublishAot> at root with no TFM/Configuration condition",Medium,https://platform.uno/docs/articles/features/using-skia-desktop.html
55,Performance,Never block on async with .Result or .Wait(),Blocking on a Task from the UI thread deadlocks because the awaiter cannot resume on the captured SynchronizationContext — always await async APIs through to the event handler,Await async methods all the way up; in libraries call ConfigureAwait(false) to avoid context capture,Calling .Result .Wait() or GetAwaiter().GetResult() on a Task from the UI thread,"private async void OnLoadClick(object s, RoutedEventArgs e) { var data = await _api.GetAsync(); Items = data; }","private void OnLoadClick(object s, RoutedEventArgs e) { var data = _api.GetAsync().Result; } // deadlocks on UI thread",High,https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/
56,Styling,Define ThemeDictionaries for Light Dark and HighContrast,Resources placed inside ResourceDictionary.ThemeDictionaries entries are automatically swapped when the system theme changes — required for theme-aware brushes,Wrap brushes in a ThemeDictionaries dictionary keyed by Light Dark and HighContrast in App.xaml or page resources,Defining a single brush at the root and missing dark/high-contrast variants,"<ResourceDictionary.ThemeDictionaries><ResourceDictionary x:Key=""Light""><SolidColorBrush x:Key=""Brand"" Color=""#005A9E""/></ResourceDictionary><ResourceDictionary x:Key=""Dark""><SolidColorBrush x:Key=""Brand"" Color=""#3A96DD""/></ResourceDictionary></ResourceDictionary.ThemeDictionaries>","<SolidColorBrush x:Key=""Brand"" Color=""#005A9E""/> at root with no theme variants",Medium,https://platform.uno/docs/articles/features/working-with-themes.html
57,Architecture,Use Uno.Sdk with UnoFeatures,Uno.Sdk is the modern single-project SDK that auto-resolves Uno.WinUI Uno.Toolkit Material and other packages from a UnoFeatures property — declare features by name instead of hand-managing dozens of PackageReferences,Declare features in the csproj via <UnoFeatures>...</UnoFeatures> and let the SDK resolve transitive packages,Hand-adding every Uno.* PackageReference and matching version numbers across packages,"<Project Sdk=""Uno.Sdk""><PropertyGroup><UnoFeatures>Material;Hosting;Toolkit;Logging;MVVM</UnoFeatures></PropertyGroup></Project>","<PackageReference Include=""Uno.WinUI""/><PackageReference Include=""Uno.Material.WinUI""/> ... duplicated per feature with mismatched versions",Medium,https://platform.uno/docs/articles/features/using-the-uno-sdk.html
58,Lifecycle,Persist desktop window state via Window.Closed,WinAppSDK and Skia desktop heads do not raise Application.Suspending — handle the Window.Closed event (and AppWindow size/position changes) to save user state when desktop apps shut down,Subscribe to MainWindow.Closed and persist any unsaved state before the window is destroyed,Relying on Application.Suspending to fire on desktop targets,"m_window.Closed += (s, e) => SaveState();","Application.Current.Suspending += SaveState; // never fires on WinAppSDK or Skia desktop",Medium,https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.window
59,Architecture,Use WinRT.Interop for native window handle on Windows,Calling Win32 APIs from a WinUI Window (file pickers icon embedding etc.) requires the HWND — retrieve it via WinRT.Interop.WindowNative.GetWindowHandle and guard the call so non-Windows targets stay unaffected,GetWindowHandle inside a #if WINDOWS block when you need the HWND,Calling WinRT.Interop in shared code without a platform guard,"#if WINDOWS\nvar hWnd = WinRT.Interop.WindowNative.GetWindowHandle(MainWindow);\n#endif","var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(MainWindow); // breaks build on iOS Android WASM",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/retrieve-hwnd
Can't render this file because it contains an unexpected character in line 23 and column 412.

View File

@@ -0,0 +1,56 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,XAML,Use x:Bind for compiled bindings,Compile-time validated bindings with better performance,x:Bind for type-safe performant bindings,{Binding} when x:Bind is available,"<TextBlock Text=""{x:Bind ViewModel.Name, Mode=OneWay}""/>","<TextBlock Text=""{Binding Name}""/>",High,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
2,XAML,Use x:Load for deferred elements,Delay creation of elements until needed,x:Load=False for hidden or conditional panels,Loading all UI elements at page load,"<StackPanel x:Name=""AdvancedPanel"" x:Load=""{x:Bind ShowAdvanced, Mode=OneWay}"">","Collapsed StackPanel that is always instantiated",Medium,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-load-attribute
3,XAML,Use x:Phase for incremental item rendering,Render list items in priority phases,x:Phase on secondary content in item DataTemplates,All template content loaded in one pass,"<TextBlock x:Phase=""1"" Text=""{x:Bind Description}""/>","Complex DataTemplate with no phasing",Medium,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-phase-attribute
4,XAML,Use x:DefaultBindMode,Reduce repetitive Mode= declarations,x:DefaultBindMode=OneWay on containers,Mode=OneWay on every individual x:Bind,"<StackPanel x:DefaultBindMode=""OneWay"">","Mode=OneWay repeated on every binding in a panel",Low,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
5,XAML,Use x:DeferLoadStrategy for legacy support,Deferred loading before x:Load was available,x:Load (preferred) or x:DeferLoadStrategy=Lazy,Eagerly loading rarely shown UI,"x:Load=""False"" (or x:DeferLoadStrategy=""Lazy"" on older targets)","Always-loaded panels toggled with Visibility",Low,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-deferloadstrategy-attribute
6,Controls,Use NavigationView for app shell,Standard UWP navigation pattern with hamburger menu,NavigationView for top-level navigation,Custom SplitView hamburger menu,"<NavigationView><NavigationView.MenuItems><NavigationViewItem Content=""Home"" Icon=""Home""/></NavigationView.MenuItems></NavigationView>","Custom SplitView with manual toggle button",High,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/navigationview
7,Controls,Use CommandBar for app actions,Standard app bar for primary commands,CommandBar with AppBarButtons,Custom StackPanel toolbar,"<CommandBar><AppBarButton Icon=""Save"" Label=""Save""/></CommandBar>","<StackPanel Orientation=""Horizontal""><Button>Save</Button></StackPanel>",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/command-bar
8,Controls,Use ContentDialog for modals,System-styled modal dialogs,ContentDialog for confirmations and input,Custom popup overlays,"<ContentDialog Title=""Confirm"" PrimaryButtonText=""Yes"" CloseButtonText=""No""/>","Grid overlay with manual focus trapping",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/dialogs-and-flyouts/dialogs
9,Controls,Use AutoSuggestBox for search,Built-in search box with suggestions,AutoSuggestBox with QuerySubmitted and SuggestionChosen,TextBox with manual suggestion popup,"<AutoSuggestBox QueryIcon=""Find"" TextChanged=""OnTextChanged"" SuggestionChosen=""OnChosen"" QuerySubmitted=""OnQuerySubmitted""/>","TextBox with custom Popup and ListBox for suggestions",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/auto-suggest-box
10,Controls,Use CalendarDatePicker and TimePicker,Platform-consistent date and time selection,Built-in date and time pickers,Custom date selection controls,"<CalendarDatePicker Header=""Start date""/><TimePicker Header=""Time""/>","TextBox with date parsing and validation",Low,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/date-and-time
11,Controls,Use PersonPicture for user avatars,Consistent avatar display with fallback initials,PersonPicture with DisplayName and ProfilePicture,Custom Ellipse with ImageBrush for avatars,"<PersonPicture DisplayName=""Jane Doe"" ProfilePicture=""{x:Bind AvatarUri}""/>","<Ellipse><Ellipse.Fill><ImageBrush ImageSource=""avatar.png""/></Ellipse.Fill></Ellipse>",Low,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/person-picture
12,Styling,Use ThemeResource for adaptive colors,Colors that switch with light and dark theme,ThemeResource for all color references,Hardcoded hex values that break in dark mode,"Foreground=""{ThemeResource SystemControlForegroundBaseHighBrush}""","Foreground=""#000000""",High,https://learn.microsoft.com/en-us/windows/uwp/design/style/color
13,Styling,Use Fluent Design materials,Acrylic translucent material for depth,Built-in Fluent materials for depth and motion,Custom shader effects for blur and reveal,"<Grid Background=""{ThemeResource SystemControlAcrylicWindowBrush}""/>","Custom CompositionEffectBrush recreating acrylic",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/style/acrylic
14,Styling,Use Lightweight Styling,Override control resource keys for subtle changes,Lightweight styling resource overrides,Full ControlTemplate copy for small tweaks,"<Button><Button.Resources><SolidColorBrush x:Key=""ButtonBackground"" Color=""Blue""/></Button.Resources></Button>","Entire ControlTemplate copied to change background",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/xaml-styles#lightweight-styling
15,Styling,Use implicit styles for consistency,TargetType without x:Key applies to all instances,Implicit Style for default control appearance,Repeating Setters on every control instance,"<Style TargetType=""Button""><Setter Property=""CornerRadius"" Value=""4""/></Style>","CornerRadius=""4"" on every Button in the page",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/xaml-styles
16,Styling,Use VisualStateManager for visual states,Define visual states with Setters that change properties when triggered,VisualStateGroup containing VisualStates with Setter targets,Toggling Visibility from code-behind on SizeChanged,"<VisualStateGroup><VisualState x:Name=""Wide""><VisualState.Setters><Setter Target=""root.Orientation"" Value=""Horizontal""/></VisualState.Setters></VisualState></VisualStateGroup>","SizeChanged handler that flips Orientation in code-behind",High,https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml
17,Navigation,Use Frame for page navigation,Windows.UI.Xaml.Controls.Frame for UWP page navigation,Frame.Navigate with typed parameters,Swapping UserControls manually,"rootFrame.Navigate(typeof(DetailPage), itemId);","contentArea.Content = new DetailPage();",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/basics/navigate-between-two-pages
18,Navigation,Handle back button correctly,Provide an in-app Back button styled with NavigationBackButtonNormalStyle and handle SystemNavigationManager.BackRequested for hardware back gamepad B and Tablet-Mode back; also handle CoreDispatcher.AcceleratorKeyActivated for Alt+Left,In-app NavigationBackButtonNormalStyle button plus SystemNavigationManager.BackRequested handler,Relying on the deprecated title-bar back button (AppViewBackButtonVisibility) or ignoring system back signals,"SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;","No back button support on phone or tablet",High,https://learn.microsoft.com/en-us/windows/uwp/ui-input/back-navigation
19,Navigation,Support deep linking with protocol activation,Respond to URI activation and toast taps,OnActivated handler with proper page routing,Ignoring activation arguments,"protected override void OnActivated(IActivatedEventArgs args) { if (args.Kind == ActivationKind.Protocol) { ... } }","Empty OnActivated ignoring URI parameters",Medium,https://learn.microsoft.com/en-us/windows/uwp/launch-resume/handle-uri-activation
20,Navigation,Use ConnectedAnimations for continuity,Smooth transitions between pages,ConnectedAnimationService for shared element transitions,Abrupt page transitions with no visual continuity,"ConnectedAnimationService.GetForCurrentView().PrepareToAnimate(""image"", sourceImage);","No transition animation between list and detail",Low,https://learn.microsoft.com/en-us/windows/uwp/design/motion/connected-animation
21,Data Binding,Implement INotifyPropertyChanged,Enable UI updates on property changes,INotifyPropertyChanged on all ViewModels,Auto-properties without notification,"public string Title { get => _title; set { _title = value; OnPropertyChanged(); } }","public string Title { get; set; } expecting UI updates",High,https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
22,Data Binding,Use ObservableCollection for lists,Collection change notifications for ItemsSources,ObservableCollection<T> for bound lists,List<T> for data-bound collections,"ObservableCollection<Item> Items { get; } = new();","List<Item> Items { get; set; } = new();",High,https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
23,Data Binding,Use function bindings with x:Bind,Call static methods directly in markup,x:Bind to static converter methods,IValueConverter for trivial transforms,"<TextBlock Visibility=""{x:Bind local:Converters.BoolToVisibility(IsActive), Mode=OneWay}""/>","Full IValueConverter class for bool to Visibility",Medium,https://learn.microsoft.com/en-us/windows/uwp/data-binding/function-bindings
24,Data Binding,Specify Mode on x:Bind,x:Bind defaults to OneTime not OneWay,Mode=OneWay or TwoWay when live updates needed,Omitting Mode and getting stale UI,"Text=""{x:Bind Title, Mode=OneWay}""","Text=""{x:Bind Title}"" expecting live updates",High,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
25,Data Binding,Use CollectionViewSource for grouping,Group and sort collections declaratively,CollectionViewSource for grouped ListView and GridView,Manual grouping logic in code-behind,"<CollectionViewSource x:Key=""GroupedItems"" IsSourceGrouped=""True"" Source=""{x:Bind GroupedData}""/>","Manual loop building grouped StackPanels",Medium,https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
26,Performance,Use ListView and GridView virtualization,Only creates containers for visible items,Default virtualization in ListView and GridView,Setting ItemsPanel to non-virtualizing panel,"<ListView ItemsSource=""{x:Bind Items}""/> (virtualizes by default)","<ListView><ListView.ItemsPanel><ItemsPanelTemplate><StackPanel/></ItemsPanelTemplate></ListView.ItemsPanel></ListView>",High,https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-gridview-and-listview
27,Performance,Use ISupportIncrementalLoading,Load data on demand as user scrolls,ISupportIncrementalLoading for large datasets,Loading entire collection upfront,"class IncrementalSource : ObservableCollection<Item>, ISupportIncrementalLoading","await LoadAll() loading 50K items at startup",Medium,https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
28,Performance,Reduce XAML visual tree depth,Simpler trees layout and render faster,Flat templates with minimal nesting,Deeply nested panels in DataTemplates,"<StackPanel><TextBlock/><TextBlock/></StackPanel> in item template","<Grid><Border><StackPanel><Grid>... 8 levels in item template",Medium,https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-xaml-loading
29,Performance,Use compiled bindings in DataTemplates,x:Bind in templates requires x:DataType,x:DataType on DataTemplate for compiled bindings,{Binding} in item templates for large lists,"<DataTemplate x:DataType=""local:Item""><TextBlock Text=""{x:Bind Name}""/></DataTemplate>","<DataTemplate><TextBlock Text=""{Binding Name}""/></DataTemplate>",High,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
30,Performance,Profile with Visual Studio diagnostics,Measure before optimizing,Application Timeline and Memory Usage tools,Guessing at performance problems,"VS Diagnostic Tools > Application Timeline","Optimizing without profiling data",Medium,https://learn.microsoft.com/en-us/visualstudio/profiling/application-timeline
31,Threading,Use async/await for all IO,Keep UI thread responsive,async/await for file network and database operations,Synchronous IO blocking the UI thread,"var file = await StorageFile.GetFileFromPathAsync(path);","StorageFile.GetFileFromPathAsync(path).AsTask().Result;",High,https://learn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-universal-windows-platform-apps
32,Threading,Use CoreDispatcher for UI thread access,Post work back to the UI thread from background,Dispatcher.RunAsync from background threads,Touching UI elements from background threads,"await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => Status = ""Done"");","textBlock.Text = ""Done"" from Task.Run",High,https://learn.microsoft.com/en-us/uwp/api/windows.ui.core.coredispatcher
33,Threading,Offload CPU work with Task.Run,Keep compute-heavy work off UI thread,Task.Run for CPU-bound operations,Heavy computation blocking UI,"var result = await Task.Run(() => ProcessData(items));","var result = ProcessData(items); freezing UI",High,https://learn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-universal-windows-platform-apps
34,Threading,Use IProgress for status updates,Report progress from background operations,IProgress<T> for progress reporting to UI,Polling shared variables for progress,"var progress = new Progress<int>(p => ProgressBar.Value = p); await Task.Run(() => Process(progress));","while (!done) { await Task.Delay(100); check shared field; }",Medium,https://learn.microsoft.com/en-us/dotnet/api/system.progress-1
35,Adaptive,Use AdaptiveTrigger for responsive layouts,MinWindowWidth and MinWindowHeight triggers fire at standard breakpoints (640 small / 1008 medium),AdaptiveTrigger inside VisualState.StateTriggers with the 640 and 1008 breakpoints,Fixed layouts for a single screen size,"<VisualState.StateTriggers><AdaptiveTrigger MinWindowWidth=""640""/></VisualState.StateTriggers>","Single-column layout at all widths",High,https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml
36,Adaptive,Design for multiple device families,Phone tablet desktop Xbox and HoloLens,DeviceFamily-specific views and resources,Desktop-only design ignoring other form factors,"DeviceFamily-Mobile/MainPage.xaml for phone-specific layout","Fixed 1920x1080 layout",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/layout/screen-sizes-and-breakpoints-for-responsive-design
37,Adaptive,Use RelativePanel for adaptive positioning,Controls position relative to each other,RelativePanel for layouts that reflow at breakpoints,Absolute positioning or fixed margins,"<Button RelativePanel.Below=""title"" RelativePanel.AlignLeftWithPanel=""True""/>","<Button Margin=""0,60,0,0""/> calculated from title height",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml#relativepanel
38,Adaptive,Support multi-window with secondary views,Open detached views with CoreApplication.CreateNewView and ApplicationViewSwitcher,CreateNewView and TryShowAsStandaloneAsync for multi-document scenarios,Single-window assumptions when scenarios benefit from secondary views,"var view = CoreApplication.CreateNewView(); await view.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { /* set content */ });","Modal overlay used for content that should be a separate window",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/layout/show-multiple-views
39,Accessibility,Set AutomationProperties,Enable Narrator and screen reader support,AutomationProperties.Name on all interactive controls,Controls without accessible names,"<AppBarButton AutomationProperties.Name=""Save document"" Icon=""Save""/>","<AppBarButton Icon=""Save""/> without name",High,https://learn.microsoft.com/en-us/windows/uwp/design/accessibility/basic-accessibility-information
40,Accessibility,Support keyboard and gamepad,All functions reachable without touch,Tab navigation XYFocus and access keys,Touch-only interactions,"<Button AccessKey=""S"" XYFocusDown=""{x:Bind OtherButton}""/>","No keyboard or gamepad support",High,https://learn.microsoft.com/en-us/windows/uwp/design/input/keyboard-interactions
41,Accessibility,Support contrast themes,Respect system contrast themes (renamed from high contrast in Windows 11),ThemeResource brushes that adapt to contrast themes,Hardcoded colors that vanish under contrast themes,"Foreground=""{ThemeResource SystemControlForegroundBaseHighBrush}""","Foreground=""#444444""",High,https://learn.microsoft.com/en-us/windows/uwp/design/accessibility/high-contrast-themes
42,Accessibility,Test with Narrator and Accessibility Insights,Validate screen reader and automation compliance,Regular Narrator walkthrough and Accessibility Insights scan,Shipping without accessibility testing,"Accessibility Insights FastPass on every page","No accessibility testing before release",Medium,https://accessibilityinsights.io/
43,Architecture,Use MVVM pattern,Separate View ViewModel and Model,ViewModel with INotifyPropertyChanged and ICommand,Business logic in code-behind,"ViewModel bound via DataContext with commands","MainPage.xaml.cs with database calls and UI logic",Medium,https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvm
44,Architecture,Use Template Studio for scaffolding,Proven project templates with navigation and services,Windows Template Studio for new UWP projects,Blank project with manual boilerplate,"Template Studio with MVVM Toolkit and navigation service","Blank App template building everything from scratch",Low,https://github.com/microsoft/TemplateStudio
45,Architecture,Use dependency injection,Register services for testability,Microsoft.Extensions.DI for service resolution,Static singletons and manual construction,"services.AddTransient<MainViewModel>(); services.AddSingleton<IDataService, DataService>();","DataService.Instance or new DataService() everywhere",Medium,https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection
46,Architecture,Keep platform APIs behind abstractions,Isolate WinRT APIs from business logic,Interfaces wrapping StorageFile FilePicker etc,Direct WinRT calls in ViewModels,"IFileService wrapping FileOpenPicker and StorageFile","FileOpenPicker usage directly in ViewModel",Medium,https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvm
47,Lifecycle,Handle suspend and resume,UWP apps are suspended when not in foreground,Save state in OnSuspending and restore in OnLaunched,Ignoring app lifecycle losing user state,"Application.Current.Suspending += (s, e) => SaveState();","No suspend handler losing in-progress form data",High,https://learn.microsoft.com/en-us/windows/uwp/launch-resume/app-lifecycle
48,Lifecycle,Use ExtendedExecutionSession for background work,Request extended time for unfinished operations,ExtendedExecutionSession for saving or uploads,Assuming background work completes after suspend,"var session = new ExtendedExecutionSession { Reason = ExtendedExecutionReason.SavingData };","Long upload with no extended execution that gets killed on suspend",Medium,https://learn.microsoft.com/en-us/windows/uwp/launch-resume/run-minimized-with-extended-execution
49,Lifecycle,Handle prelaunch,Apps must opt in to prelaunch via CoreApplication.EnablePrelaunch(true) starting in Windows 10 1607; check LaunchActivatedEventArgs.PrelaunchActivated to skip user-visible work,Opt in with EnablePrelaunch and skip heavy init when PrelaunchActivated is true,Performing full initialization or navigating during prelaunch,"CoreApplication.EnablePrelaunch(true); if (e.PrelaunchActivated) return; // skip heavy init","Loading all data and navigating on prelaunch",Medium,https://learn.microsoft.com/en-us/windows/uwp/launch-resume/handle-app-prelaunch
50,Testing,Unit test ViewModels,Test logic without UI framework dependencies,xUnit or MSTest on ViewModel methods,Testing only through the running app,"[Fact] public async Task Load_PopulatesItems() { await vm.LoadAsync(); Assert.NotEmpty(vm.Items); }","Manual testing by tapping through the app",Medium,https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
51,Testing,Use WinAppDriver with Appium for UI tests,Automated UI testing for UWP (Coded UI Test was deprecated in Visual Studio 2019); WinAppDriver v1 is in low-maintenance mode and Appium 2 is the modern direction,WinAppDriver with Appium for end-to-end tests,Manual regression testing,"session.FindElementByAccessibilityId(""SaveButton"").Click();","Manual click-through testing before each release",Medium,https://github.com/microsoft/WinAppDriver
52,Testing,Test on multiple device families,Behavior varies across phone desktop and Xbox,Test on device emulators and real hardware,Desktop-only testing,"Test on Mobile emulator and Xbox dev mode","Only running on local desktop",Medium,https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portal
53,Architecture,Prefer WinUI 3 for new projects,UWP is in maintenance mode and Microsoft recommends WinUI 3 and Windows App SDK for new development,WinUI 3 with Windows App SDK for new desktop apps,Starting new projects on UWP when WinUI 3 is available,"New project with Microsoft.WindowsAppSDK and WinUI 3","New UWP project for a desktop-only app in 2024+",Medium,https://learn.microsoft.com/en-us/windows/apps/get-started/
54,Architecture,Plan migration to Windows App SDK,Microsoft provides migration guides from UWP to WinUI 3,Incremental migration using XAML Islands or full port to WinUI 3,Ignoring migration path and accumulating UWP technical debt,"Follow UWP to WinUI 3 migration guide for existing apps","Continuing major feature development on UWP without migration plan",Medium,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/migrate-to-windows-app-sdk/overall-migration-strategy
55,Lifecycle,Use a deferral when saving async state on suspend,Suspending grants only ~5 seconds before the OS may terminate; await work needs SuspendingOperation.GetDeferral and Complete or save returns before it finishes,GetDeferral around async save calls and Complete in finally,Async work that returns the suspending handler before completion,"async void OnSuspending(object s, SuspendingEventArgs e) { var d = e.SuspendingOperation.GetDeferral(); try { await SaveAsync(); } finally { d.Complete(); } }","async void OnSuspending(object s, SuspendingEventArgs e) { await SaveAsync(); } // handler returns before save completes",Medium,https://learn.microsoft.com/en-us/windows/uwp/launch-resume/app-lifecycle
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 XAML Use x:Bind for compiled bindings Compile-time validated bindings with better performance x:Bind for type-safe performant bindings {Binding} when x:Bind is available <TextBlock Text="{x:Bind ViewModel.Name, Mode=OneWay}"/> <TextBlock Text="{Binding Name}"/> High https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
3 2 XAML Use x:Load for deferred elements Delay creation of elements until needed x:Load=False for hidden or conditional panels Loading all UI elements at page load <StackPanel x:Name="AdvancedPanel" x:Load="{x:Bind ShowAdvanced, Mode=OneWay}"> Collapsed StackPanel that is always instantiated Medium https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-load-attribute
4 3 XAML Use x:Phase for incremental item rendering Render list items in priority phases x:Phase on secondary content in item DataTemplates All template content loaded in one pass <TextBlock x:Phase="1" Text="{x:Bind Description}"/> Complex DataTemplate with no phasing Medium https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-phase-attribute
5 4 XAML Use x:DefaultBindMode Reduce repetitive Mode= declarations x:DefaultBindMode=OneWay on containers Mode=OneWay on every individual x:Bind <StackPanel x:DefaultBindMode="OneWay"> Mode=OneWay repeated on every binding in a panel Low https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
6 5 XAML Use x:DeferLoadStrategy for legacy support Deferred loading before x:Load was available x:Load (preferred) or x:DeferLoadStrategy=Lazy Eagerly loading rarely shown UI x:Load="False" (or x:DeferLoadStrategy="Lazy" on older targets) Always-loaded panels toggled with Visibility Low https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-deferloadstrategy-attribute
7 6 Controls Use NavigationView for app shell Standard UWP navigation pattern with hamburger menu NavigationView for top-level navigation Custom SplitView hamburger menu <NavigationView><NavigationView.MenuItems><NavigationViewItem Content="Home" Icon="Home"/></NavigationView.MenuItems></NavigationView> Custom SplitView with manual toggle button High https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/navigationview
8 7 Controls Use CommandBar for app actions Standard app bar for primary commands CommandBar with AppBarButtons Custom StackPanel toolbar <CommandBar><AppBarButton Icon="Save" Label="Save"/></CommandBar> <StackPanel Orientation="Horizontal"><Button>Save</Button></StackPanel> Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/command-bar
9 8 Controls Use ContentDialog for modals System-styled modal dialogs ContentDialog for confirmations and input Custom popup overlays <ContentDialog Title="Confirm" PrimaryButtonText="Yes" CloseButtonText="No"/> Grid overlay with manual focus trapping Medium https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/dialogs-and-flyouts/dialogs
10 9 Controls Use AutoSuggestBox for search Built-in search box with suggestions AutoSuggestBox with QuerySubmitted and SuggestionChosen TextBox with manual suggestion popup <AutoSuggestBox QueryIcon="Find" TextChanged="OnTextChanged" SuggestionChosen="OnChosen" QuerySubmitted="OnQuerySubmitted"/> TextBox with custom Popup and ListBox for suggestions Medium https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/auto-suggest-box
11 10 Controls Use CalendarDatePicker and TimePicker Platform-consistent date and time selection Built-in date and time pickers Custom date selection controls <CalendarDatePicker Header="Start date"/><TimePicker Header="Time"/> TextBox with date parsing and validation Low https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/date-and-time
12 11 Controls Use PersonPicture for user avatars Consistent avatar display with fallback initials PersonPicture with DisplayName and ProfilePicture Custom Ellipse with ImageBrush for avatars <PersonPicture DisplayName="Jane Doe" ProfilePicture="{x:Bind AvatarUri}"/> <Ellipse><Ellipse.Fill><ImageBrush ImageSource="avatar.png"/></Ellipse.Fill></Ellipse> Low https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/person-picture
13 12 Styling Use ThemeResource for adaptive colors Colors that switch with light and dark theme ThemeResource for all color references Hardcoded hex values that break in dark mode Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}" Foreground="#000000" High https://learn.microsoft.com/en-us/windows/uwp/design/style/color
14 13 Styling Use Fluent Design materials Acrylic translucent material for depth Built-in Fluent materials for depth and motion Custom shader effects for blur and reveal <Grid Background="{ThemeResource SystemControlAcrylicWindowBrush}"/> Custom CompositionEffectBrush recreating acrylic Medium https://learn.microsoft.com/en-us/windows/uwp/design/style/acrylic
15 14 Styling Use Lightweight Styling Override control resource keys for subtle changes Lightweight styling resource overrides Full ControlTemplate copy for small tweaks <Button><Button.Resources><SolidColorBrush x:Key="ButtonBackground" Color="Blue"/></Button.Resources></Button> Entire ControlTemplate copied to change background Medium https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/xaml-styles#lightweight-styling
16 15 Styling Use implicit styles for consistency TargetType without x:Key applies to all instances Implicit Style for default control appearance Repeating Setters on every control instance <Style TargetType="Button"><Setter Property="CornerRadius" Value="4"/></Style> CornerRadius="4" on every Button in the page Medium https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/xaml-styles
17 16 Styling Use VisualStateManager for visual states Define visual states with Setters that change properties when triggered VisualStateGroup containing VisualStates with Setter targets Toggling Visibility from code-behind on SizeChanged <VisualStateGroup><VisualState x:Name="Wide"><VisualState.Setters><Setter Target="root.Orientation" Value="Horizontal"/></VisualState.Setters></VisualState></VisualStateGroup> SizeChanged handler that flips Orientation in code-behind High https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml
18 17 Navigation Use Frame for page navigation Windows.UI.Xaml.Controls.Frame for UWP page navigation Frame.Navigate with typed parameters Swapping UserControls manually rootFrame.Navigate(typeof(DetailPage), itemId); contentArea.Content = new DetailPage(); Medium https://learn.microsoft.com/en-us/windows/uwp/design/basics/navigate-between-two-pages
19 18 Navigation Handle back button correctly Provide an in-app Back button styled with NavigationBackButtonNormalStyle and handle SystemNavigationManager.BackRequested for hardware back gamepad B and Tablet-Mode back; also handle CoreDispatcher.AcceleratorKeyActivated for Alt+Left In-app NavigationBackButtonNormalStyle button plus SystemNavigationManager.BackRequested handler Relying on the deprecated title-bar back button (AppViewBackButtonVisibility) or ignoring system back signals SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested; No back button support on phone or tablet High https://learn.microsoft.com/en-us/windows/uwp/ui-input/back-navigation
20 19 Navigation Support deep linking with protocol activation Respond to URI activation and toast taps OnActivated handler with proper page routing Ignoring activation arguments protected override void OnActivated(IActivatedEventArgs args) { if (args.Kind == ActivationKind.Protocol) { ... } } Empty OnActivated ignoring URI parameters Medium https://learn.microsoft.com/en-us/windows/uwp/launch-resume/handle-uri-activation
21 20 Navigation Use ConnectedAnimations for continuity Smooth transitions between pages ConnectedAnimationService for shared element transitions Abrupt page transitions with no visual continuity ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("image", sourceImage); No transition animation between list and detail Low https://learn.microsoft.com/en-us/windows/uwp/design/motion/connected-animation
22 21 Data Binding Implement INotifyPropertyChanged Enable UI updates on property changes INotifyPropertyChanged on all ViewModels Auto-properties without notification public string Title { get => _title; set { _title = value; OnPropertyChanged(); } } public string Title { get; set; } expecting UI updates High https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
23 22 Data Binding Use ObservableCollection for lists Collection change notifications for ItemsSources ObservableCollection<T> for bound lists List<T> for data-bound collections ObservableCollection<Item> Items { get; } = new(); List<Item> Items { get; set; } = new(); High https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
24 23 Data Binding Use function bindings with x:Bind Call static methods directly in markup x:Bind to static converter methods IValueConverter for trivial transforms <TextBlock Visibility="{x:Bind local:Converters.BoolToVisibility(IsActive), Mode=OneWay}"/> Full IValueConverter class for bool to Visibility Medium https://learn.microsoft.com/en-us/windows/uwp/data-binding/function-bindings
25 24 Data Binding Specify Mode on x:Bind x:Bind defaults to OneTime not OneWay Mode=OneWay or TwoWay when live updates needed Omitting Mode and getting stale UI Text="{x:Bind Title, Mode=OneWay}" Text="{x:Bind Title}" expecting live updates High https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
26 25 Data Binding Use CollectionViewSource for grouping Group and sort collections declaratively CollectionViewSource for grouped ListView and GridView Manual grouping logic in code-behind <CollectionViewSource x:Key="GroupedItems" IsSourceGrouped="True" Source="{x:Bind GroupedData}"/> Manual loop building grouped StackPanels Medium https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
27 26 Performance Use ListView and GridView virtualization Only creates containers for visible items Default virtualization in ListView and GridView Setting ItemsPanel to non-virtualizing panel <ListView ItemsSource="{x:Bind Items}"/> (virtualizes by default) <ListView><ListView.ItemsPanel><ItemsPanelTemplate><StackPanel/></ItemsPanelTemplate></ListView.ItemsPanel></ListView> High https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-gridview-and-listview
28 27 Performance Use ISupportIncrementalLoading Load data on demand as user scrolls ISupportIncrementalLoading for large datasets Loading entire collection upfront class IncrementalSource : ObservableCollection<Item>, ISupportIncrementalLoading await LoadAll() loading 50K items at startup Medium https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
29 28 Performance Reduce XAML visual tree depth Simpler trees layout and render faster Flat templates with minimal nesting Deeply nested panels in DataTemplates <StackPanel><TextBlock/><TextBlock/></StackPanel> in item template <Grid><Border><StackPanel><Grid>... 8 levels in item template Medium https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-xaml-loading
30 29 Performance Use compiled bindings in DataTemplates x:Bind in templates requires x:DataType x:DataType on DataTemplate for compiled bindings {Binding} in item templates for large lists <DataTemplate x:DataType="local:Item"><TextBlock Text="{x:Bind Name}"/></DataTemplate> <DataTemplate><TextBlock Text="{Binding Name}"/></DataTemplate> High https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
31 30 Performance Profile with Visual Studio diagnostics Measure before optimizing Application Timeline and Memory Usage tools Guessing at performance problems VS Diagnostic Tools > Application Timeline Optimizing without profiling data Medium https://learn.microsoft.com/en-us/visualstudio/profiling/application-timeline
32 31 Threading Use async/await for all IO Keep UI thread responsive async/await for file network and database operations Synchronous IO blocking the UI thread var file = await StorageFile.GetFileFromPathAsync(path); StorageFile.GetFileFromPathAsync(path).AsTask().Result; High https://learn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-universal-windows-platform-apps
33 32 Threading Use CoreDispatcher for UI thread access Post work back to the UI thread from background Dispatcher.RunAsync from background threads Touching UI elements from background threads await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => Status = "Done"); textBlock.Text = "Done" from Task.Run High https://learn.microsoft.com/en-us/uwp/api/windows.ui.core.coredispatcher
34 33 Threading Offload CPU work with Task.Run Keep compute-heavy work off UI thread Task.Run for CPU-bound operations Heavy computation blocking UI var result = await Task.Run(() => ProcessData(items)); var result = ProcessData(items); freezing UI High https://learn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-universal-windows-platform-apps
35 34 Threading Use IProgress for status updates Report progress from background operations IProgress<T> for progress reporting to UI Polling shared variables for progress var progress = new Progress<int>(p => ProgressBar.Value = p); await Task.Run(() => Process(progress)); while (!done) { await Task.Delay(100); check shared field; } Medium https://learn.microsoft.com/en-us/dotnet/api/system.progress-1
36 35 Adaptive Use AdaptiveTrigger for responsive layouts MinWindowWidth and MinWindowHeight triggers fire at standard breakpoints (640 small / 1008 medium) AdaptiveTrigger inside VisualState.StateTriggers with the 640 and 1008 breakpoints Fixed layouts for a single screen size <VisualState.StateTriggers><AdaptiveTrigger MinWindowWidth="640"/></VisualState.StateTriggers> Single-column layout at all widths High https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml
37 36 Adaptive Design for multiple device families Phone tablet desktop Xbox and HoloLens DeviceFamily-specific views and resources Desktop-only design ignoring other form factors DeviceFamily-Mobile/MainPage.xaml for phone-specific layout Fixed 1920x1080 layout Medium https://learn.microsoft.com/en-us/windows/uwp/design/layout/screen-sizes-and-breakpoints-for-responsive-design
38 37 Adaptive Use RelativePanel for adaptive positioning Controls position relative to each other RelativePanel for layouts that reflow at breakpoints Absolute positioning or fixed margins <Button RelativePanel.Below="title" RelativePanel.AlignLeftWithPanel="True"/> <Button Margin="0,60,0,0"/> calculated from title height Medium https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml#relativepanel
39 38 Adaptive Support multi-window with secondary views Open detached views with CoreApplication.CreateNewView and ApplicationViewSwitcher CreateNewView and TryShowAsStandaloneAsync for multi-document scenarios Single-window assumptions when scenarios benefit from secondary views var view = CoreApplication.CreateNewView(); await view.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { /* set content */ }); Modal overlay used for content that should be a separate window Medium https://learn.microsoft.com/en-us/windows/uwp/design/layout/show-multiple-views
40 39 Accessibility Set AutomationProperties Enable Narrator and screen reader support AutomationProperties.Name on all interactive controls Controls without accessible names <AppBarButton AutomationProperties.Name="Save document" Icon="Save"/> <AppBarButton Icon="Save"/> without name High https://learn.microsoft.com/en-us/windows/uwp/design/accessibility/basic-accessibility-information
41 40 Accessibility Support keyboard and gamepad All functions reachable without touch Tab navigation XYFocus and access keys Touch-only interactions <Button AccessKey="S" XYFocusDown="{x:Bind OtherButton}"/> No keyboard or gamepad support High https://learn.microsoft.com/en-us/windows/uwp/design/input/keyboard-interactions
42 41 Accessibility Support contrast themes Respect system contrast themes (renamed from high contrast in Windows 11) ThemeResource brushes that adapt to contrast themes Hardcoded colors that vanish under contrast themes Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}" Foreground="#444444" High https://learn.microsoft.com/en-us/windows/uwp/design/accessibility/high-contrast-themes
43 42 Accessibility Test with Narrator and Accessibility Insights Validate screen reader and automation compliance Regular Narrator walkthrough and Accessibility Insights scan Shipping without accessibility testing Accessibility Insights FastPass on every page No accessibility testing before release Medium https://accessibilityinsights.io/
44 43 Architecture Use MVVM pattern Separate View ViewModel and Model ViewModel with INotifyPropertyChanged and ICommand Business logic in code-behind ViewModel bound via DataContext with commands MainPage.xaml.cs with database calls and UI logic Medium https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvm
45 44 Architecture Use Template Studio for scaffolding Proven project templates with navigation and services Windows Template Studio for new UWP projects Blank project with manual boilerplate Template Studio with MVVM Toolkit and navigation service Blank App template building everything from scratch Low https://github.com/microsoft/TemplateStudio
46 45 Architecture Use dependency injection Register services for testability Microsoft.Extensions.DI for service resolution Static singletons and manual construction services.AddTransient<MainViewModel>(); services.AddSingleton<IDataService, DataService>(); DataService.Instance or new DataService() everywhere Medium https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection
47 46 Architecture Keep platform APIs behind abstractions Isolate WinRT APIs from business logic Interfaces wrapping StorageFile FilePicker etc Direct WinRT calls in ViewModels IFileService wrapping FileOpenPicker and StorageFile FileOpenPicker usage directly in ViewModel Medium https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvm
48 47 Lifecycle Handle suspend and resume UWP apps are suspended when not in foreground Save state in OnSuspending and restore in OnLaunched Ignoring app lifecycle losing user state Application.Current.Suspending += (s, e) => SaveState(); No suspend handler losing in-progress form data High https://learn.microsoft.com/en-us/windows/uwp/launch-resume/app-lifecycle
49 48 Lifecycle Use ExtendedExecutionSession for background work Request extended time for unfinished operations ExtendedExecutionSession for saving or uploads Assuming background work completes after suspend var session = new ExtendedExecutionSession { Reason = ExtendedExecutionReason.SavingData }; Long upload with no extended execution that gets killed on suspend Medium https://learn.microsoft.com/en-us/windows/uwp/launch-resume/run-minimized-with-extended-execution
50 49 Lifecycle Handle prelaunch Apps must opt in to prelaunch via CoreApplication.EnablePrelaunch(true) starting in Windows 10 1607; check LaunchActivatedEventArgs.PrelaunchActivated to skip user-visible work Opt in with EnablePrelaunch and skip heavy init when PrelaunchActivated is true Performing full initialization or navigating during prelaunch CoreApplication.EnablePrelaunch(true); if (e.PrelaunchActivated) return; // skip heavy init Loading all data and navigating on prelaunch Medium https://learn.microsoft.com/en-us/windows/uwp/launch-resume/handle-app-prelaunch
51 50 Testing Unit test ViewModels Test logic without UI framework dependencies xUnit or MSTest on ViewModel methods Testing only through the running app [Fact] public async Task Load_PopulatesItems() { await vm.LoadAsync(); Assert.NotEmpty(vm.Items); } Manual testing by tapping through the app Medium https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
52 51 Testing Use WinAppDriver with Appium for UI tests Automated UI testing for UWP (Coded UI Test was deprecated in Visual Studio 2019); WinAppDriver v1 is in low-maintenance mode and Appium 2 is the modern direction WinAppDriver with Appium for end-to-end tests Manual regression testing session.FindElementByAccessibilityId("SaveButton").Click(); Manual click-through testing before each release Medium https://github.com/microsoft/WinAppDriver
53 52 Testing Test on multiple device families Behavior varies across phone desktop and Xbox Test on device emulators and real hardware Desktop-only testing Test on Mobile emulator and Xbox dev mode Only running on local desktop Medium https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portal
54 53 Architecture Prefer WinUI 3 for new projects UWP is in maintenance mode and Microsoft recommends WinUI 3 and Windows App SDK for new development WinUI 3 with Windows App SDK for new desktop apps Starting new projects on UWP when WinUI 3 is available New project with Microsoft.WindowsAppSDK and WinUI 3 New UWP project for a desktop-only app in 2024+ Medium https://learn.microsoft.com/en-us/windows/apps/get-started/
55 54 Architecture Plan migration to Windows App SDK Microsoft provides migration guides from UWP to WinUI 3 Incremental migration using XAML Islands or full port to WinUI 3 Ignoring migration path and accumulating UWP technical debt Follow UWP to WinUI 3 migration guide for existing apps Continuing major feature development on UWP without migration plan Medium https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/migrate-to-windows-app-sdk/overall-migration-strategy
56 55 Lifecycle Use a deferral when saving async state on suspend Suspending grants only ~5 seconds before the OS may terminate; await work needs SuspendingOperation.GetDeferral and Complete or save returns before it finishes GetDeferral around async save calls and Complete in finally Async work that returns the suspending handler before completion async void OnSuspending(object s, SuspendingEventArgs e) { var d = e.SuspendingOperation.GetDeferral(); try { await SaveAsync(); } finally { d.Complete(); } } async void OnSuspending(object s, SuspendingEventArgs e) { await SaveAsync(); } // handler returns before save completes Medium https://learn.microsoft.com/en-us/windows/uwp/launch-resume/app-lifecycle

View File

@@ -0,0 +1,60 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,XAML,Use x:Bind for compiled bindings,Compile-time checked bindings with better performance,x:Bind for type-safe bindings,{Binding} when x:Bind works,"<TextBlock Text=""{x:Bind ViewModel.Title, Mode=OneWay}""/>","<TextBlock Text=""{Binding Title}""/>",High,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
2,XAML,Use x:Load for deferred loading,Only instantiate UI elements when needed,x:Load=False for hidden panels and dialogs,Loading all UI upfront,"<StackPanel x:Load=""{x:Bind ShowDetails, Mode=OneWay}"">","Always-loaded collapsed panels",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-load-attribute
3,XAML,Use x:Phase for incremental rendering,Load list items in phases for smooth scrolling,x:Phase on secondary content in DataTemplates,Loading all template content in phase 0,"<TextBlock x:Phase=""1"" Text=""{x:Bind Description}""/>","All content in single phase for complex templates",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
4,XAML,Use x:DefaultBindMode,Set default binding mode for a scope,x:DefaultBindMode=OneWay on containers with many bindings,Mode=OneWay on every individual x:Bind,"<StackPanel x:DefaultBindMode=""OneWay"">","Mode=OneWay repeated on 20 bindings",Low,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
5,Controls,Use NavigationView for app navigation,WinUI 3 NavigationView with Left Top and LeftCompact display modes plus footer items,NavigationView with PaneDisplayMode for main app shell,Custom hamburger menu implementation,"<NavigationView><NavigationView.MenuItems><NavigationViewItem Content=""Home""/></NavigationView.MenuItems></NavigationView>","Custom SplitView with manual hamburger button",High,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/navigationview
6,Controls,Use InfoBar for status messages,Non-intrusive informational messages,InfoBar for success warning and error messages,Custom styled StackPanel for status,"<InfoBar IsOpen=""True"" Severity=""Warning"" Title=""Update available""/>","<StackPanel Background=""Yellow""><TextBlock Text=""Warning""/></StackPanel>",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/infobar
7,Controls,Use TeachingTip for onboarding,Contextual tips attached to UI elements,TeachingTip for feature discovery,Custom popup for teaching,"<TeachingTip Target=""{x:Bind SearchBox}"" Title=""Try searching""/>","Custom Popup positioned near target element",Low,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/dialogs-and-flyouts/teaching-tip
8,Controls,Use ContentDialog for modal interactions,Standard modal dialog pattern,ContentDialog for confirmations and input,Custom overlay Panel as dialog,"<ContentDialog Title=""Delete?"" PrimaryButtonText=""Delete"" CloseButtonText=""Cancel""/>","Grid overlay with manual focus trapping",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/dialogs-and-flyouts/dialogs
9,Controls,Use BreadcrumbBar for hierarchy,Show navigation path in hierarchical apps,BreadcrumbBar for folder or category navigation,Manual TextBlock breadcrumb chain,"<BreadcrumbBar ItemsSource=""{x:Bind Breadcrumbs}""/>","<StackPanel Orientation=""Horizontal""><TextBlock Text=""Home > Settings > Display""/></StackPanel>",Low,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/breadcrumbbar
10,Styling,Use Lightweight Styling,Override control sub-properties via resources,Lightweight styling resource keys to tweak controls,Full ControlTemplate override for small changes,"<Button><Button.Resources><ResourceDictionary><ResourceDictionary.ThemeDictionaries><ResourceDictionary x:Key=""Light""><SolidColorBrush x:Key=""ButtonBackground"" Color=""MediumSlateBlue""/></ResourceDictionary></ResourceDictionary.ThemeDictionaries></ResourceDictionary></Button.Resources></Button>","Full ControlTemplate copy to change background color",High,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/xaml-styles#lightweight-styling
11,Styling,Use WinUI theme resources,Consistent Fluent Design colors and brushes,WinUI theme resource keys for colors,Hardcoded hex color values,"Background=""{ThemeResource CardBackgroundFillColorDefaultBrush}""","Background=""#FF2D2D30""",High,https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/color
12,Styling,Support light and dark themes,Respect user and system theme preference,ThemeResource for theme-adaptive values,Hardcoded colors that break in dark mode,"Foreground=""{ThemeResource TextFillColorPrimaryBrush}""","Foreground=""Black""",High,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/xaml-theme-resources
13,Styling,Use Fluent Design system,Acrylic Mica Reveal and rounded corners,Built-in Fluent materials and effects,Custom blur and shadow implementations,"<Grid Background=""{ThemeResource AcrylicInAppFillColorDefaultBrush}""/>","Custom CompositionBrush recreating acrylic",Medium,https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/materials
14,Navigation,Use Frame for page navigation,Microsoft.UI.Xaml.Controls.Frame for WinUI 3 page navigation,Frame.Navigate with page types and parameters,Swapping UserControls in a ContentControl,"rootFrame.Navigate(typeof(SettingsPage), parameter);","contentArea.Content = new SettingsControl();",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/navigation/navigate-between-two-pages
15,Navigation,Pass typed navigation parameters,Type-safe data passing between pages,Typed parameter in OnNavigatedTo,Dictionary or string parsing for parameters,"protected override void OnNavigatedTo(NavigationEventArgs e) { var item = (Item)e.Parameter; }","var id = int.Parse(e.Parameter.ToString());",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/navigation/navigate-between-two-pages
16,Navigation,Handle back navigation,WinUI 3 uses NavigationView.BackRequested instead of UWP SystemNavigationManager,Register NavigationView.BackRequested handler and manage back stack,"Ignoring back navigation","navigationView.BackRequested += OnBackRequested;","No back button support",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/navigation/navigation-history-and-backwards-navigation
17,Navigation,Use deep linking,Handle protocol activation so URIs route to the right page,Register protocol then check ExtendedActivationKind.Protocol on activation,Single entry point ignoring activation context,"AppInstance.GetCurrent().GetActivatedEventArgs() with ExtendedActivationKind.Protocol","Ignoring activation arguments",Medium,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle-rich-activation
18,Data Binding,Use ObservableCollection for lists,Notifies UI of collection changes,ObservableCollection<T> for bound ItemsSources,List<T> for bound collections,"ObservableCollection<Item> Items { get; } = new();","List<Item> Items { get; set; } = new();",High,https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth
19,Data Binding,Use INotifyPropertyChanged,Enable property change notification for UI updates,INotifyPropertyChanged on ViewModels,Properties without notification,"public string Name { get => _name; set => SetProperty(ref _name, value); }","public string Name { get; set; } without notification",High,https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth
20,Data Binding,Use function binding with x:Bind,Call methods directly in bindings,x:Bind with method references for transforms,IValueConverter for simple logic,"<TextBlock Visibility=""{x:Bind local:Converters.BoolToVisibility(IsActive), Mode=OneWay}""/>","IValueConverter class for bool to visibility",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/function-bindings
21,Data Binding,Specify Mode explicitly on x:Bind,x:Bind defaults to OneTime not OneWay,Mode=OneWay or Mode=TwoWay when updates needed,Forgetting Mode and getting stale UI,"Text=""{x:Bind Title, Mode=OneWay}""","Text=""{x:Bind Title}"" expecting live updates",High,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
22,Performance,Use ItemsRepeater for custom lists,Virtualizing layout with full control,ItemsRepeater for custom list layouts,ListView for highly customized item layouts,"<ItemsRepeater ItemsSource=""{x:Bind Items}""><ItemsRepeater.Layout><StackLayout/></ItemsRepeater.Layout></ItemsRepeater>","ListView with heavily modified template and removed chrome",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/items-repeater
23,Performance,Use incremental loading,Load data on demand as user scrolls,ISupportIncrementalLoading for large data sets,Loading entire dataset upfront,"class IncrementalItemSource : ObservableCollection<Item>, ISupportIncrementalLoading","await LoadAllItems() on page load for 10K items",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth
24,Performance,Reduce visual tree complexity,Simpler trees render faster,Minimal nesting in DataTemplates,Deeply nested panels in item templates,"<StackPanel><TextBlock/><TextBlock/></StackPanel>","<Grid><Border><StackPanel><Grid>... 8 levels deep",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/performance/optimize-xaml-loading
25,Performance,Use compiled bindings over reflection,x:Bind generates code at compile time,x:Bind for hot paths and list items,{Binding} in DataTemplates and frequently updated UI,"<DataTemplate x:DataType=""local:Item""><TextBlock Text=""{x:Bind Name}""/></DataTemplate>","<DataTemplate><TextBlock Text=""{Binding Name}""/></DataTemplate>",High,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
26,Threading,Use DispatcherQueue not Dispatcher,WinUI 3 uses Microsoft.UI.Dispatching.DispatcherQueue instead of UWP CoreDispatcher,DispatcherQueue.TryEnqueue for UI thread access,Dispatcher.RunAsync (UWP pattern),"_dispatcherQueue.TryEnqueue(() => Status = ""Done"");","Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ...);",High,https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.dispatching.dispatcherqueue
27,Threading,Use async/await for IO operations,Keep UI responsive during file and network access,async/await for IO so the UI thread keeps rendering,Synchronous IO on UI thread,"var data = await httpClient.GetStringAsync(url);","var data = httpClient.GetStringAsync(url).Result;",High,https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/
28,Threading,Use Task.Run for CPU-bound work,Offload compute to thread pool,Task.Run for heavy computation,Long-running CPU work on UI thread,"var result = await Task.Run(() => ProcessLargeDataSet());","var result = ProcessLargeDataSet(); blocking UI",High,https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming
29,Packaging,Use WinAppSDK correctly,Windows App SDK provides the runtime,WinAppSDK NuGet package and WindowsAppSDK bootstrapper,Mixing UWP and WinUI 3 APIs,"<PackageReference Include=""Microsoft.WindowsAppSDK""/>","Using Windows.UI.Xaml instead of Microsoft.UI.Xaml",High,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/
30,Packaging,Use unpackaged or packaged appropriately,Choose deployment model for your scenario,Packaged (MSIX) for Store distribution,Unpackaged without considering API limitations,"<WindowsPackageType>None</WindowsPackageType> for unpackaged","Assuming all APIs work in unpackaged mode",Medium,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/deploy-packaged-apps
31,Packaging,Use single-project MSIX,Simplified packaging for single app,Single-project MSIX packaging,Separate WAP project when not needed,"<EnableMsixTooling>true</EnableMsixTooling> in csproj","Separate Windows Application Packaging project for simple apps",Low,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/single-project-msix
32,Accessibility,Set AutomationProperties,Enable Narrator and screen reader support,AutomationProperties.Name on all interactive controls,Controls without accessible names,"<Button AutomationProperties.Name=""Save document""><FontIcon Glyph=""&#xE74E;""/></Button>","<Button><FontIcon Glyph=""&#xE74E;""/></Button> without name",High,https://learn.microsoft.com/en-us/windows/apps/design/accessibility/basic-accessibility-information
33,Accessibility,Support keyboard navigation,Full keyboard accessibility,Tab navigation and access keys for all controls,Mouse-only interactions,"<Button AccessKey=""S"" Content=""Save""/>","Interactive elements unreachable by keyboard",High,https://learn.microsoft.com/en-us/windows/apps/develop/input/keyboard-interactions
34,Accessibility,Use proper heading levels,Screen readers use headings for navigation,AutomationProperties.HeadingLevel on section headers,All text at same heading level,"<TextBlock AutomationProperties.HeadingLevel=""Level1"" Text=""Settings""/>","<TextBlock Style=""{StaticResource TitleTextBlockStyle}""/> without heading level",Medium,https://learn.microsoft.com/en-us/windows/apps/design/accessibility/basic-accessibility-information
35,Accessibility,Support high contrast,Respect system high contrast settings,ThemeResource brushes that adapt to high contrast,Hardcoded colors ignoring high contrast,"Foreground=""{ThemeResource TextFillColorPrimaryBrush}""","Foreground=""#333333""",High,https://learn.microsoft.com/en-us/windows/apps/design/accessibility/high-contrast-themes
36,Accessibility,Test with Accessibility Insights,Validate accessibility compliance,Accessibility Insights for Windows scanning,Manual accessibility checking only,"Run Accessibility Insights FastPass on every page","Ship without accessibility testing",Medium,https://accessibilityinsights.io/
37,Architecture,Use MVVM with CommunityToolkit,Source generators reduce boilerplate,[ObservableProperty] and [RelayCommand] attributes,Manual INotifyPropertyChanged and ICommand,"[ObservableProperty] private string _title; [RelayCommand] private void Save() { }","Full INotifyPropertyChanged implementation per property",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
38,Architecture,Use dependency injection,Register services with Microsoft.Extensions.DI,IServiceProvider for ViewModel and service resolution,new ViewModel() and new Service() everywhere,"services.AddTransient<MainViewModel>(); services.AddSingleton<IDataService, DataService>();","new MainViewModel(new DataService()) in code-behind",Medium,https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection/overview
39,Architecture,Use Template Studio patterns,Start with proven architectural templates,Template Studio for WinUI 3 project scaffolding,Blank project with manual setup for complex apps,"WinUI 3 Template Studio with MVVM and navigation","Blank App template for production app",Low,https://github.com/microsoft/TemplateStudio
40,Architecture,Separate platform from business logic,Keep business logic in .NET Standard or shared libraries,Business logic in separate class library,Business logic mixed with WinUI types,"Shared.Core project with no WinUI references","ViewModel importing Microsoft.UI.Xaml types",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
41,Architecture,Use WinUI 3 Window management,Proper window lifecycle management,AppWindow API for multi-window scenarios,Single Window assumption in complex apps,"var appWindow = this.AppWindow;","Relying solely on MainWindow for everything",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/manage-app-windows
42,Testing,Unit test ViewModels,Test logic independent of UI framework,xUnit or MSTest on ViewModel properties and commands,Testing through UI only,"[Fact] public async Task LoadItems_PopulatesCollection() { await vm.LoadCommand.ExecuteAsync(null); Assert.NotEmpty(vm.Items); }","Manual testing by running the app",Medium,https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
43,Testing,Use WinAppDriver for UI tests,Automated UI testing for WinUI 3,WinAppDriver or Appium for end-to-end tests,Manual regression testing,"var element = session.FindElementByAccessibilityId(""SaveButton""); element.Click();","Click-through manual testing",Medium,https://github.com/microsoft/WinAppDriver
44,Testing,Mock WinRT APIs in tests,Isolate tests from platform dependencies,Interface wrappers around WinRT APIs,Direct WinRT API calls in testable code,"IFileService wrapping StorageFile APIs","StorageFile.GetFileFromPathAsync directly in ViewModel",Medium,https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
45,Controls,Use NumberBox for numeric input,Built-in numeric entry with validation formatting and spin buttons,NumberBox with Minimum Maximum and SpinButtonPlacementMode,TextBox with manual numeric parsing and validation,"<NumberBox Value=""{x:Bind Quantity, Mode=TwoWay}"" Minimum=""0"" Maximum=""100"" SpinButtonPlacementMode=""Inline""/>","TextBox with regex validation for numbers",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/number-box
46,Controls,Use Expander for collapsible sections,Expandable content area with header for progressive disclosure,Expander for settings groups and optional content,Manual visibility toggling with buttons,"<Expander Header=""Advanced Settings""><StackPanel><ToggleSwitch Header=""Debug mode""/></StackPanel></Expander>","Button toggling StackPanel.Visibility for collapsible content",Low,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/expander
47,Controls,Use ProgressRing and ProgressBar for loading,Built-in loading indicators for determinate and indeterminate states,ProgressRing for indeterminate and ProgressBar for determinate progress,Custom spinning animation or text-based loading indicators,"<ProgressRing IsActive=""{x:Bind IsLoading, Mode=OneWay}""/>","<TextBlock Text=""Loading..."" Visibility=""{x:Bind IsLoading}""/>",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/progress-controls
48,Layout,Use VisualStateManager for responsive layouts,Adapt UI layout to window size using adaptive triggers,AdaptiveTrigger with MinWindowWidth for responsive breakpoints,Fixed layouts that break at different window sizes,"<VisualState><VisualState.StateTriggers><AdaptiveTrigger MinWindowWidth=""720""/></VisualState.StateTriggers><VisualState.Setters><Setter Target=""sidebar.Visibility"" Value=""Visible""/></VisualState.Setters></VisualState>","Fixed two-column layout at all window sizes",High,https://learn.microsoft.com/en-us/windows/apps/develop/ui/layouts-with-xaml
49,Lifecycle,Handle app activation and launch,WinUI 3 apps receive activation events for URI and notification launches,Check LaunchActivatedEventArgs in OnLaunched for activation context,Ignoring activation arguments losing deep link context,"protected override void OnLaunched(LaunchActivatedEventArgs args) { if (args.Arguments.Contains(""settings"")) NavigateToSettings(); }","Empty OnLaunched ignoring all activation parameters",Medium,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle-rich-activation
50,Lifecycle,Use single instancing with AppInstance,Prevent multiple app windows competing for resources,AppInstance.FindOrRegisterForKey for single-instance enforcement,Multiple instances with conflicting state,"var instance = AppInstance.FindOrRegisterForKey(""main""); if (!instance.IsCurrent) { await instance.RedirectActivationToAsync(args); }","No instance management allowing duplicate windows",Medium,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle-instancing
51,Lifecycle,Save and restore app state,Persist UI state across app restarts for continuity (ApplicationData APIs require packaged apps; unpackaged apps must use file IO or registry),Save state to local settings on window close or navigation,Losing user context on every restart,"ApplicationData.Current.LocalSettings.Values[""lastPage""] = currentPage;","No state persistence losing navigation position on restart",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/data/store-and-retrieve-app-data
52,Styling,Choose Mica vs Acrylic by surface lifetime,Mica is for long-lived primary surfaces like main windows; Acrylic is for transient light-dismiss surfaces like flyouts and context menus,Mica on root window backgrounds and Acrylic on flyouts and overlays,Acrylic on the main window or Mica on transient flyouts,"<Window.SystemBackdrop><MicaBackdrop/></Window.SystemBackdrop> ... <FlyoutPresenter Background=""{ThemeResource AcrylicInAppFillColorDefaultBrush}""/>","Acrylic on every Window background causing battery and perf cost",Medium,https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/materials
53,Styling,Set SystemBackdrop on Window directly,WinUI 3 1.3+ exposes Window.SystemBackdrop with MicaBackdrop and DesktopAcrylicBackdrop classes replacing manual MicaController plumbing,Window.SystemBackdrop in XAML or code,Hand-rolled MicaController wiring when SystemBackdrop API is available,"<Window.SystemBackdrop><MicaBackdrop Kind=""Base""/></Window.SystemBackdrop>","var ctrl = new Microsoft.UI.Composition.SystemBackdrops.MicaController(); ctrl.AddSystemBackdropTarget(this.As<ICompositionSupportsSystemBackdrop>());",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/system-backdrops
54,Architecture,Open secondary windows with new Window,WinUI 3 supports multiple top-level windows; each Window owns an AppWindow accessible via Window.AppWindow for size and position control,new Window().Activate() for secondary windows tracking them in App state,Faking multi-window via main-window content swaps or ContentDialog,"var settings = new SettingsWindow(); settings.Activate();","MainWindow.Content = new SettingsView(); when a separate window is needed",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/manage-app-windows
55,Architecture,Extend client area into the title bar,Use Window.ExtendsContentIntoTitleBar with SetTitleBar to host custom XAML in the chrome while preserving caption buttons,ExtendsContentIntoTitleBar=true plus SetTitleBar(element) for custom drag region,Hardcoded chrome height or custom caption buttons that break with theme and size changes,"this.ExtendsContentIntoTitleBar = true; this.SetTitleBar(AppTitleBar);","Padding=""0,32,0,0"" to reserve space without SetTitleBar leaves window non-draggable",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/title-bar
56,Accessibility,Use KeyboardAccelerator for shortcuts,Map Ctrl/Alt/Shift combinations to commands using KeyboardAccelerator on UIElement,KeyboardAccelerator with Modifiers and Key on relevant controls,Manual KeyDown handlers swallowing shortcuts,"<Button Command=""{x:Bind SaveCommand}""><Button.KeyboardAccelerators><KeyboardAccelerator Modifiers=""Control"" Key=""S""/></Button.KeyboardAccelerators></Button>","Window.PreviewKeyDown=""OnKeyDown"" with switch over args.Key",High,https://learn.microsoft.com/en-us/windows/apps/develop/input/keyboard-accelerators
57,Styling,Organize resources with merged dictionaries,Share styles and brushes via App.xaml MergedDictionaries instead of duplicating per page,MergedDictionaries in App.xaml for shared styles brushes and colors,Duplicating SolidColorBrush definitions on every page,"<Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source=""Themes/Brushes.xaml""/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources>",SolidColorBrush Color hardcoded inline on every page,Medium,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/xaml-resource-dictionary
58,Architecture,Use AsyncRelayCommand for async commands,AsyncRelayCommand exposes IsRunning and supports cancellation for IO bound work,[RelayCommand] on async Task method or AsyncRelayCommand for IO work,async void event handlers or fire-and-forget Task.Run from button click,"[RelayCommand] private async Task LoadAsync(CancellationToken ct) { Items = await _service.FetchAsync(ct); }","private async void Button_Click(object s, RoutedEventArgs e) { await LoadAsync(); }",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/asyncrelaycommand
59,Architecture,Use ILogger for structured logging,Microsoft.Extensions.Logging ILogger<T> with DI for structured leveled logs,ILogger<T> injected via constructor for diagnostic logging,Debug.WriteLine or Console.WriteLine for app diagnostics,"public MainViewModel(ILogger<MainViewModel> logger) { _logger = logger; } _logger.LogInformation(""Loaded {Count} items"", count);","Debug.WriteLine($""Loaded {count} items"");",Medium,https://learn.microsoft.com/en-us/dotnet/core/extensions/logging/overview
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 XAML Use x:Bind for compiled bindings Compile-time checked bindings with better performance x:Bind for type-safe bindings {Binding} when x:Bind works <TextBlock Text="{x:Bind ViewModel.Title, Mode=OneWay}"/> <TextBlock Text="{Binding Title}"/> High https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
3 2 XAML Use x:Load for deferred loading Only instantiate UI elements when needed x:Load=False for hidden panels and dialogs Loading all UI upfront <StackPanel x:Load="{x:Bind ShowDetails, Mode=OneWay}"> Always-loaded collapsed panels Medium https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-load-attribute
4 3 XAML Use x:Phase for incremental rendering Load list items in phases for smooth scrolling x:Phase on secondary content in DataTemplates Loading all template content in phase 0 <TextBlock x:Phase="1" Text="{x:Bind Description}"/> All content in single phase for complex templates Medium https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
5 4 XAML Use x:DefaultBindMode Set default binding mode for a scope x:DefaultBindMode=OneWay on containers with many bindings Mode=OneWay on every individual x:Bind <StackPanel x:DefaultBindMode="OneWay"> Mode=OneWay repeated on 20 bindings Low https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
6 5 Controls Use NavigationView for app navigation WinUI 3 NavigationView with Left Top and LeftCompact display modes plus footer items NavigationView with PaneDisplayMode for main app shell Custom hamburger menu implementation <NavigationView><NavigationView.MenuItems><NavigationViewItem Content="Home"/></NavigationView.MenuItems></NavigationView> Custom SplitView with manual hamburger button High https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/navigationview
7 6 Controls Use InfoBar for status messages Non-intrusive informational messages InfoBar for success warning and error messages Custom styled StackPanel for status <InfoBar IsOpen="True" Severity="Warning" Title="Update available"/> <StackPanel Background="Yellow"><TextBlock Text="Warning"/></StackPanel> Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/infobar
8 7 Controls Use TeachingTip for onboarding Contextual tips attached to UI elements TeachingTip for feature discovery Custom popup for teaching <TeachingTip Target="{x:Bind SearchBox}" Title="Try searching"/> Custom Popup positioned near target element Low https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/dialogs-and-flyouts/teaching-tip
9 8 Controls Use ContentDialog for modal interactions Standard modal dialog pattern ContentDialog for confirmations and input Custom overlay Panel as dialog <ContentDialog Title="Delete?" PrimaryButtonText="Delete" CloseButtonText="Cancel"/> Grid overlay with manual focus trapping Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/dialogs-and-flyouts/dialogs
10 9 Controls Use BreadcrumbBar for hierarchy Show navigation path in hierarchical apps BreadcrumbBar for folder or category navigation Manual TextBlock breadcrumb chain <BreadcrumbBar ItemsSource="{x:Bind Breadcrumbs}"/> <StackPanel Orientation="Horizontal"><TextBlock Text="Home > Settings > Display"/></StackPanel> Low https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/breadcrumbbar
11 10 Styling Use Lightweight Styling Override control sub-properties via resources Lightweight styling resource keys to tweak controls Full ControlTemplate override for small changes <Button><Button.Resources><ResourceDictionary><ResourceDictionary.ThemeDictionaries><ResourceDictionary x:Key="Light"><SolidColorBrush x:Key="ButtonBackground" Color="MediumSlateBlue"/></ResourceDictionary></ResourceDictionary.ThemeDictionaries></ResourceDictionary></Button.Resources></Button> Full ControlTemplate copy to change background color High https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/xaml-styles#lightweight-styling
12 11 Styling Use WinUI theme resources Consistent Fluent Design colors and brushes WinUI theme resource keys for colors Hardcoded hex color values Background="{ThemeResource CardBackgroundFillColorDefaultBrush}" Background="#FF2D2D30" High https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/color
13 12 Styling Support light and dark themes Respect user and system theme preference ThemeResource for theme-adaptive values Hardcoded colors that break in dark mode Foreground="{ThemeResource TextFillColorPrimaryBrush}" Foreground="Black" High https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/xaml-theme-resources
14 13 Styling Use Fluent Design system Acrylic Mica Reveal and rounded corners Built-in Fluent materials and effects Custom blur and shadow implementations <Grid Background="{ThemeResource AcrylicInAppFillColorDefaultBrush}"/> Custom CompositionBrush recreating acrylic Medium https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/materials
15 14 Navigation Use Frame for page navigation Microsoft.UI.Xaml.Controls.Frame for WinUI 3 page navigation Frame.Navigate with page types and parameters Swapping UserControls in a ContentControl rootFrame.Navigate(typeof(SettingsPage), parameter); contentArea.Content = new SettingsControl(); Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/navigation/navigate-between-two-pages
16 15 Navigation Pass typed navigation parameters Type-safe data passing between pages Typed parameter in OnNavigatedTo Dictionary or string parsing for parameters protected override void OnNavigatedTo(NavigationEventArgs e) { var item = (Item)e.Parameter; } var id = int.Parse(e.Parameter.ToString()); Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/navigation/navigate-between-two-pages
17 16 Navigation Handle back navigation WinUI 3 uses NavigationView.BackRequested instead of UWP SystemNavigationManager Register NavigationView.BackRequested handler and manage back stack Ignoring back navigation navigationView.BackRequested += OnBackRequested; No back button support Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/navigation/navigation-history-and-backwards-navigation
18 17 Navigation Use deep linking Handle protocol activation so URIs route to the right page Register protocol then check ExtendedActivationKind.Protocol on activation Single entry point ignoring activation context AppInstance.GetCurrent().GetActivatedEventArgs() with ExtendedActivationKind.Protocol Ignoring activation arguments Medium https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle-rich-activation
19 18 Data Binding Use ObservableCollection for lists Notifies UI of collection changes ObservableCollection<T> for bound ItemsSources List<T> for bound collections ObservableCollection<Item> Items { get; } = new(); List<Item> Items { get; set; } = new(); High https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth
20 19 Data Binding Use INotifyPropertyChanged Enable property change notification for UI updates INotifyPropertyChanged on ViewModels Properties without notification public string Name { get => _name; set => SetProperty(ref _name, value); } public string Name { get; set; } without notification High https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth
21 20 Data Binding Use function binding with x:Bind Call methods directly in bindings x:Bind with method references for transforms IValueConverter for simple logic <TextBlock Visibility="{x:Bind local:Converters.BoolToVisibility(IsActive), Mode=OneWay}"/> IValueConverter class for bool to visibility Medium https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/function-bindings
22 21 Data Binding Specify Mode explicitly on x:Bind x:Bind defaults to OneTime not OneWay Mode=OneWay or Mode=TwoWay when updates needed Forgetting Mode and getting stale UI Text="{x:Bind Title, Mode=OneWay}" Text="{x:Bind Title}" expecting live updates High https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
23 22 Performance Use ItemsRepeater for custom lists Virtualizing layout with full control ItemsRepeater for custom list layouts ListView for highly customized item layouts <ItemsRepeater ItemsSource="{x:Bind Items}"><ItemsRepeater.Layout><StackLayout/></ItemsRepeater.Layout></ItemsRepeater> ListView with heavily modified template and removed chrome Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/items-repeater
24 23 Performance Use incremental loading Load data on demand as user scrolls ISupportIncrementalLoading for large data sets Loading entire dataset upfront class IncrementalItemSource : ObservableCollection<Item>, ISupportIncrementalLoading await LoadAllItems() on page load for 10K items Medium https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth
25 24 Performance Reduce visual tree complexity Simpler trees render faster Minimal nesting in DataTemplates Deeply nested panels in item templates <StackPanel><TextBlock/><TextBlock/></StackPanel> <Grid><Border><StackPanel><Grid>... 8 levels deep Medium https://learn.microsoft.com/en-us/windows/apps/develop/performance/optimize-xaml-loading
26 25 Performance Use compiled bindings over reflection x:Bind generates code at compile time x:Bind for hot paths and list items {Binding} in DataTemplates and frequently updated UI <DataTemplate x:DataType="local:Item"><TextBlock Text="{x:Bind Name}"/></DataTemplate> <DataTemplate><TextBlock Text="{Binding Name}"/></DataTemplate> High https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
27 26 Threading Use DispatcherQueue not Dispatcher WinUI 3 uses Microsoft.UI.Dispatching.DispatcherQueue instead of UWP CoreDispatcher DispatcherQueue.TryEnqueue for UI thread access Dispatcher.RunAsync (UWP pattern) _dispatcherQueue.TryEnqueue(() => Status = "Done"); Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ...); High https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.dispatching.dispatcherqueue
28 27 Threading Use async/await for IO operations Keep UI responsive during file and network access async/await for IO so the UI thread keeps rendering Synchronous IO on UI thread var data = await httpClient.GetStringAsync(url); var data = httpClient.GetStringAsync(url).Result; High https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/
29 28 Threading Use Task.Run for CPU-bound work Offload compute to thread pool Task.Run for heavy computation Long-running CPU work on UI thread var result = await Task.Run(() => ProcessLargeDataSet()); var result = ProcessLargeDataSet(); blocking UI High https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming
30 29 Packaging Use WinAppSDK correctly Windows App SDK provides the runtime WinAppSDK NuGet package and WindowsAppSDK bootstrapper Mixing UWP and WinUI 3 APIs <PackageReference Include="Microsoft.WindowsAppSDK"/> Using Windows.UI.Xaml instead of Microsoft.UI.Xaml High https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/
31 30 Packaging Use unpackaged or packaged appropriately Choose deployment model for your scenario Packaged (MSIX) for Store distribution Unpackaged without considering API limitations <WindowsPackageType>None</WindowsPackageType> for unpackaged Assuming all APIs work in unpackaged mode Medium https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/deploy-packaged-apps
32 31 Packaging Use single-project MSIX Simplified packaging for single app Single-project MSIX packaging Separate WAP project when not needed <EnableMsixTooling>true</EnableMsixTooling> in csproj Separate Windows Application Packaging project for simple apps Low https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/single-project-msix
33 32 Accessibility Set AutomationProperties Enable Narrator and screen reader support AutomationProperties.Name on all interactive controls Controls without accessible names <Button AutomationProperties.Name="Save document"><FontIcon Glyph="&#xE74E;"/></Button> <Button><FontIcon Glyph="&#xE74E;"/></Button> without name High https://learn.microsoft.com/en-us/windows/apps/design/accessibility/basic-accessibility-information
34 33 Accessibility Support keyboard navigation Full keyboard accessibility Tab navigation and access keys for all controls Mouse-only interactions <Button AccessKey="S" Content="Save"/> Interactive elements unreachable by keyboard High https://learn.microsoft.com/en-us/windows/apps/develop/input/keyboard-interactions
35 34 Accessibility Use proper heading levels Screen readers use headings for navigation AutomationProperties.HeadingLevel on section headers All text at same heading level <TextBlock AutomationProperties.HeadingLevel="Level1" Text="Settings"/> <TextBlock Style="{StaticResource TitleTextBlockStyle}"/> without heading level Medium https://learn.microsoft.com/en-us/windows/apps/design/accessibility/basic-accessibility-information
36 35 Accessibility Support high contrast Respect system high contrast settings ThemeResource brushes that adapt to high contrast Hardcoded colors ignoring high contrast Foreground="{ThemeResource TextFillColorPrimaryBrush}" Foreground="#333333" High https://learn.microsoft.com/en-us/windows/apps/design/accessibility/high-contrast-themes
37 36 Accessibility Test with Accessibility Insights Validate accessibility compliance Accessibility Insights for Windows scanning Manual accessibility checking only Run Accessibility Insights FastPass on every page Ship without accessibility testing Medium https://accessibilityinsights.io/
38 37 Architecture Use MVVM with CommunityToolkit Source generators reduce boilerplate [ObservableProperty] and [RelayCommand] attributes Manual INotifyPropertyChanged and ICommand [ObservableProperty] private string _title; [RelayCommand] private void Save() { } Full INotifyPropertyChanged implementation per property Medium https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
39 38 Architecture Use dependency injection Register services with Microsoft.Extensions.DI IServiceProvider for ViewModel and service resolution new ViewModel() and new Service() everywhere services.AddTransient<MainViewModel>(); services.AddSingleton<IDataService, DataService>(); new MainViewModel(new DataService()) in code-behind Medium https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection/overview
40 39 Architecture Use Template Studio patterns Start with proven architectural templates Template Studio for WinUI 3 project scaffolding Blank project with manual setup for complex apps WinUI 3 Template Studio with MVVM and navigation Blank App template for production app Low https://github.com/microsoft/TemplateStudio
41 40 Architecture Separate platform from business logic Keep business logic in .NET Standard or shared libraries Business logic in separate class library Business logic mixed with WinUI types Shared.Core project with no WinUI references ViewModel importing Microsoft.UI.Xaml types Medium https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
42 41 Architecture Use WinUI 3 Window management Proper window lifecycle management AppWindow API for multi-window scenarios Single Window assumption in complex apps var appWindow = this.AppWindow; Relying solely on MainWindow for everything Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/manage-app-windows
43 42 Testing Unit test ViewModels Test logic independent of UI framework xUnit or MSTest on ViewModel properties and commands Testing through UI only [Fact] public async Task LoadItems_PopulatesCollection() { await vm.LoadCommand.ExecuteAsync(null); Assert.NotEmpty(vm.Items); } Manual testing by running the app Medium https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
44 43 Testing Use WinAppDriver for UI tests Automated UI testing for WinUI 3 WinAppDriver or Appium for end-to-end tests Manual regression testing var element = session.FindElementByAccessibilityId("SaveButton"); element.Click(); Click-through manual testing Medium https://github.com/microsoft/WinAppDriver
45 44 Testing Mock WinRT APIs in tests Isolate tests from platform dependencies Interface wrappers around WinRT APIs Direct WinRT API calls in testable code IFileService wrapping StorageFile APIs StorageFile.GetFileFromPathAsync directly in ViewModel Medium https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
46 45 Controls Use NumberBox for numeric input Built-in numeric entry with validation formatting and spin buttons NumberBox with Minimum Maximum and SpinButtonPlacementMode TextBox with manual numeric parsing and validation <NumberBox Value="{x:Bind Quantity, Mode=TwoWay}" Minimum="0" Maximum="100" SpinButtonPlacementMode="Inline"/> TextBox with regex validation for numbers Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/number-box
47 46 Controls Use Expander for collapsible sections Expandable content area with header for progressive disclosure Expander for settings groups and optional content Manual visibility toggling with buttons <Expander Header="Advanced Settings"><StackPanel><ToggleSwitch Header="Debug mode"/></StackPanel></Expander> Button toggling StackPanel.Visibility for collapsible content Low https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/expander
48 47 Controls Use ProgressRing and ProgressBar for loading Built-in loading indicators for determinate and indeterminate states ProgressRing for indeterminate and ProgressBar for determinate progress Custom spinning animation or text-based loading indicators <ProgressRing IsActive="{x:Bind IsLoading, Mode=OneWay}"/> <TextBlock Text="Loading..." Visibility="{x:Bind IsLoading}"/> Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/progress-controls
49 48 Layout Use VisualStateManager for responsive layouts Adapt UI layout to window size using adaptive triggers AdaptiveTrigger with MinWindowWidth for responsive breakpoints Fixed layouts that break at different window sizes <VisualState><VisualState.StateTriggers><AdaptiveTrigger MinWindowWidth="720"/></VisualState.StateTriggers><VisualState.Setters><Setter Target="sidebar.Visibility" Value="Visible"/></VisualState.Setters></VisualState> Fixed two-column layout at all window sizes High https://learn.microsoft.com/en-us/windows/apps/develop/ui/layouts-with-xaml
50 49 Lifecycle Handle app activation and launch WinUI 3 apps receive activation events for URI and notification launches Check LaunchActivatedEventArgs in OnLaunched for activation context Ignoring activation arguments losing deep link context protected override void OnLaunched(LaunchActivatedEventArgs args) { if (args.Arguments.Contains("settings")) NavigateToSettings(); } Empty OnLaunched ignoring all activation parameters Medium https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle-rich-activation
51 50 Lifecycle Use single instancing with AppInstance Prevent multiple app windows competing for resources AppInstance.FindOrRegisterForKey for single-instance enforcement Multiple instances with conflicting state var instance = AppInstance.FindOrRegisterForKey("main"); if (!instance.IsCurrent) { await instance.RedirectActivationToAsync(args); } No instance management allowing duplicate windows Medium https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle-instancing
52 51 Lifecycle Save and restore app state Persist UI state across app restarts for continuity (ApplicationData APIs require packaged apps; unpackaged apps must use file IO or registry) Save state to local settings on window close or navigation Losing user context on every restart ApplicationData.Current.LocalSettings.Values["lastPage"] = currentPage; No state persistence losing navigation position on restart Medium https://learn.microsoft.com/en-us/windows/apps/develop/data/store-and-retrieve-app-data
53 52 Styling Choose Mica vs Acrylic by surface lifetime Mica is for long-lived primary surfaces like main windows; Acrylic is for transient light-dismiss surfaces like flyouts and context menus Mica on root window backgrounds and Acrylic on flyouts and overlays Acrylic on the main window or Mica on transient flyouts <Window.SystemBackdrop><MicaBackdrop/></Window.SystemBackdrop> ... <FlyoutPresenter Background="{ThemeResource AcrylicInAppFillColorDefaultBrush}"/> Acrylic on every Window background causing battery and perf cost Medium https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/materials
54 53 Styling Set SystemBackdrop on Window directly WinUI 3 1.3+ exposes Window.SystemBackdrop with MicaBackdrop and DesktopAcrylicBackdrop classes replacing manual MicaController plumbing Window.SystemBackdrop in XAML or code Hand-rolled MicaController wiring when SystemBackdrop API is available <Window.SystemBackdrop><MicaBackdrop Kind="Base"/></Window.SystemBackdrop> var ctrl = new Microsoft.UI.Composition.SystemBackdrops.MicaController(); ctrl.AddSystemBackdropTarget(this.As<ICompositionSupportsSystemBackdrop>()); Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/system-backdrops
55 54 Architecture Open secondary windows with new Window WinUI 3 supports multiple top-level windows; each Window owns an AppWindow accessible via Window.AppWindow for size and position control new Window().Activate() for secondary windows tracking them in App state Faking multi-window via main-window content swaps or ContentDialog var settings = new SettingsWindow(); settings.Activate(); MainWindow.Content = new SettingsView(); when a separate window is needed Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/manage-app-windows
56 55 Architecture Extend client area into the title bar Use Window.ExtendsContentIntoTitleBar with SetTitleBar to host custom XAML in the chrome while preserving caption buttons ExtendsContentIntoTitleBar=true plus SetTitleBar(element) for custom drag region Hardcoded chrome height or custom caption buttons that break with theme and size changes this.ExtendsContentIntoTitleBar = true; this.SetTitleBar(AppTitleBar); Padding="0,32,0,0" to reserve space without SetTitleBar leaves window non-draggable Medium https://learn.microsoft.com/en-us/windows/apps/develop/title-bar
57 56 Accessibility Use KeyboardAccelerator for shortcuts Map Ctrl/Alt/Shift combinations to commands using KeyboardAccelerator on UIElement KeyboardAccelerator with Modifiers and Key on relevant controls Manual KeyDown handlers swallowing shortcuts <Button Command="{x:Bind SaveCommand}"><Button.KeyboardAccelerators><KeyboardAccelerator Modifiers="Control" Key="S"/></Button.KeyboardAccelerators></Button> Window.PreviewKeyDown="OnKeyDown" with switch over args.Key High https://learn.microsoft.com/en-us/windows/apps/develop/input/keyboard-accelerators
58 57 Styling Organize resources with merged dictionaries Share styles and brushes via App.xaml MergedDictionaries instead of duplicating per page MergedDictionaries in App.xaml for shared styles brushes and colors Duplicating SolidColorBrush definitions on every page <Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="Themes/Brushes.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources> SolidColorBrush Color hardcoded inline on every page Medium https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/xaml-resource-dictionary
59 58 Architecture Use AsyncRelayCommand for async commands AsyncRelayCommand exposes IsRunning and supports cancellation for IO bound work [RelayCommand] on async Task method or AsyncRelayCommand for IO work async void event handlers or fire-and-forget Task.Run from button click [RelayCommand] private async Task LoadAsync(CancellationToken ct) { Items = await _service.FetchAsync(ct); } private async void Button_Click(object s, RoutedEventArgs e) { await LoadAsync(); } Medium https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/asyncrelaycommand
60 59 Architecture Use ILogger for structured logging Microsoft.Extensions.Logging ILogger<T> with DI for structured leveled logs ILogger<T> injected via constructor for diagnostic logging Debug.WriteLine or Console.WriteLine for app diagnostics public MainViewModel(ILogger<MainViewModel> logger) { _logger = logger; } _logger.LogInformation("Loaded {Count} items", count); Debug.WriteLine($"Loaded {count} items"); Medium https://learn.microsoft.com/en-us/dotnet/core/extensions/logging/overview

View File

@@ -0,0 +1,57 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,XAML,Use XAML for declarative UI,Define layout and visuals in XAML not code-behind,XAML for structure and styling,Build UI trees in C# code-behind,"<Button Content=""Save"" Click=""OnSave""/>",var btn = new Button(); btn.Content = "Save";,Low,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/xaml/
2,XAML,Set x:Class on root element,Connects XAML to its code-behind partial class,x:Class on Window UserControl and Page,"Missing x:Class or mismatched namespace","<Window x:Class=""MyApp.MainWindow"">","<Window> without x:Class",High,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/xaml/
3,XAML,Use x:Name sparingly,Only name elements accessed from code-behind,x:Name when code-behind reference is needed,Naming every element,"<TextBox x:Name=""SearchBox""/>","x:Name on every control",Low,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/xaml/
4,XAML,Prefer attached properties for layout,Grid.Row Grid.Column DockPanel.Dock etc,Attached properties for panel positioning,Margin hacks for alignment,"<Button Grid.Row=""1"" Grid.Column=""2""/>","<Button Margin=""200,100,0,0""/>",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/properties/attached-properties-overview
5,XAML,Use routed events for tree-wide handling,Events bubble up or tunnel down the element tree letting parents handle child events with one handler,Handler at parent using TypeName.EventName syntax with e.Handled=true when consumed,Wiring identical handlers on every child when one parent handler suffices,"<StackPanel Button.Click=""OnAnyButtonClick"">","Click=""OnClick"" repeated on every Button under a common parent",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/events/routed-events-overview
6,Data Binding,Implement INotifyPropertyChanged,Enable UI updates when properties change,INotifyPropertyChanged on ViewModels,Public properties without notification,"public string Name { get => _name; set { if (_name != value) { _name = value; OnPropertyChanged(); } } }","public string Name { get; set; } without notification",High,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-implement-property-change-notification
7,Data Binding,Use ObservableCollection for lists,Notifies UI of add remove and reset,ObservableCollection<T> for bound collections,List<T> or Array for bound ItemsSources,"ObservableCollection<Item> Items { get; } = new();","List<Item> Items { get; set; } = new();",High,https://learn.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1
8,Data Binding,Set DataContext at the right level,Enables binding for the visual subtree,DataContext on Window or root container,DataContext on every child control,"<Window DataContext=""{Binding Source={StaticResource VM}}"">","Setting DataContext on each TextBlock individually",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/
9,Data Binding,Prefer Binding over code-behind assignments,Declarative binding keeps UI and logic separate,"{Binding Path=Name} in XAML","textBlock.Text = viewModel.Name in code-behind","<TextBlock Text=""{Binding Name}""/>","Loaded event handler that sets every property",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/data-binding-overview
10,Data Binding,Use UpdateSourceTrigger appropriately,Controls when source updates,PropertyChanged for instant feedback,Default LostFocus when search-as-you-type is needed,"Text=""{Binding Query, UpdateSourceTrigger=PropertyChanged}""","Text=""{Binding Query}"" when search-as-you-type needed",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-control-when-the-textbox-text-updates-the-source
11,Data Binding,Use IValueConverter for display transforms,Convert data for presentation without changing the model,IValueConverter for bool-to-visibility etc,Visibility properties on ViewModel,"<TextBlock Visibility=""{Binding IsActive, Converter={StaticResource BoolToVis}}""/>","public Visibility IsActiveVisibility => IsActive ? Visibility.Visible : Visibility.Collapsed;",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-convert-bound-data
12,Data Binding,Use INotifyDataErrorInfo for validation,Surface validation errors to the binding system instead of ad-hoc error UI,ObservableValidator with DataAnnotations attributes,Throwing in setters or maintaining separate error properties,"public partial class FormVm : ObservableValidator { [ObservableProperty][NotifyDataErrorInfo][Required] private string _email; }","if (string.IsNullOrEmpty(Email)) ErrorMessage = ""Required"";",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/observablevalidator
13,Layout,Use Grid for complex layouts,Rows and columns with proportional or fixed sizing,Grid with RowDefinitions and ColumnDefinitions,Canvas with absolute positions for forms,"<Grid><Grid.RowDefinitions><RowDefinition Height=""Auto""/><RowDefinition Height=""*""/></Grid.RowDefinitions></Grid>","<Canvas><TextBox Canvas.Left=""50"" Canvas.Top=""80""/></Canvas>",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/grid
14,Layout,Use StackPanel for linear content,Simple vertical or horizontal stacking,StackPanel for toolbars and simple lists,Grid with single column for linear content,"<StackPanel Orientation=""Horizontal""><Button/><Button/></StackPanel>","<Grid><Grid.RowDefinitions>..12 Auto rows..</Grid.RowDefinitions></Grid>",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/stackpanel
15,Layout,Use DockPanel for docked regions,Dock children to edges with last child filling,DockPanel for shell layouts (menu top sidebar left),Nested StackPanels to simulate docking,"<DockPanel><Menu DockPanel.Dock=""Top""/><TreeView DockPanel.Dock=""Left""/><Frame/></DockPanel>","Nested StackPanels with fixed widths for shell",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/dockpanel
16,Layout,Avoid hardcoded sizes,Use Auto Star and MinWidth/MaxWidth,Proportional sizing with * and Auto,Fixed pixel widths on resizable content,"<ColumnDefinition Width=""2*""/>","<ColumnDefinition Width=""350""/> on main content",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/grid
17,Layout,Use ScrollViewer for overflow,Wrap content that may exceed available space,ScrollViewer around long forms or lists,Clipping content without scroll,"<ScrollViewer><StackPanel>...long content...</StackPanel></ScrollViewer>","<StackPanel> that clips off-screen items",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/scrollviewer
18,Styling,Use Resource Dictionaries,Centralize colors brushes and styles,ResourceDictionary in App.xaml for theme values,Inline colors and font sizes on every element,"<SolidColorBrush x:Key=""PrimaryBrush"" Color=""#0078D4""/>","<Button Background=""#0078D4""/> repeated everywhere",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/systems/xaml-resources-overview
19,Styling,Use pack URIs for embedded resources,Reference embedded images fonts and resource dictionaries via the pack scheme,"pack://application:,,, syntax for cross-assembly assets",File-system paths for resources compiled into the assembly,"<Image Source=""pack://application:,,,/MyApp;component/Resources/icon.png""/>","<Image Source=""C:\Resources\icon.png""/>",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/app-development/pack-uris-in-wpf
20,Styling,Use implicit styles,Apply a Style to all instances of a TargetType,Style with TargetType and no x:Key for defaults,Manually styling every Button instance,"<Style TargetType=""Button""><Setter Property=""Padding"" Value=""12,6""/></Style>","Padding=""12,6"" on every Button",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/styles-templates-overview
21,Styling,Use explicit styles with x:Key and BasedOn,Named variant styles that inherit from a base via BasedOn,x:Key styles that BasedOn an implicit or named style,Duplicating setters across variants,"<Style x:Key=""PrimaryButton"" TargetType=""Button"" BasedOn=""{StaticResource {x:Type Button}}"">","Copy-pasting 10 Setters into a second Style",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/styles-templates-overview
22,Styling,Prefer StaticResource over DynamicResource,StaticResource is resolved once and faster,StaticResource for values that do not change at runtime,DynamicResource for static theme values,"Background=""{StaticResource PrimaryBrush}""","Background=""{DynamicResource PrimaryBrush}"" when theme never changes",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/systems/xaml-resources-overview
23,Styling,Use ControlTemplate for full control,Override default rendering of a control,ControlTemplate when built-in styles are insufficient,Nesting extra panels to hide the default template,"<ControlTemplate TargetType=""Button""><Border><ContentPresenter/></Border></ControlTemplate>","Wrapping Button in Border to fake a custom look",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/how-to-create-apply-template
24,Styling,Use DataTemplate for data presentation,Define how data objects render in ItemsControls,DataTemplate for ListBox ComboBox and ItemsControl items,ToString overrides for display,"<DataTemplate DataType=""{x:Type local:Person}""><TextBlock Text=""{Binding FullName}""/></DataTemplate>","Relying on ToString() in ListBox",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/data-templating-overview
25,Styling,Use Fluent theme on .NET 9+,ThemeMode applies the Windows 11 Fluent style; values are Light Dark System and None (default Aero2),ThemeMode on Application or Window,Legacy Aero2 styling for new Windows 11 apps,"<Application ThemeMode=""System"">","<Application> with default Aero2 look",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/whats-new/net90
26,Commands,Use ICommand for user actions,Decouple UI actions from logic,ICommand implementations (RelayCommand DelegateCommand),Click event handlers in code-behind,"<Button Command=""{Binding SaveCommand}""/>","<Button Click=""OnSaveClick""/> with logic in code-behind",High,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/commanding-overview
27,Commands,Use CanExecute for enable/disable,Automatically disable controls when action unavailable; call NotifyCanExecuteChanged when state changes,CanExecute returning false to disable buttons,IsEnabled binding to a separate bool,"new RelayCommand(Save, () => !IsBusy)","<Button IsEnabled=""{Binding IsNotBusy}""/>",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/commanding-overview
28,Commands,Use RelayCommand or DelegateCommand,Avoid implementing ICommand from scratch every time,RelayCommand (CommunityToolkit.Mvvm) or DelegateCommand (Prism),New ICommand class per command,"[RelayCommand] private void Save() { }","class SaveCommand : ICommand { ... } for each action",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/relaycommand
29,Commands,Use AsyncRelayCommand for async operations,Tracks IsRunning and disables the command while it executes preventing re-entry,AsyncRelayCommand or [RelayCommand] on async Task method,async void event handlers in code-behind,[RelayCommand] private async Task SaveAsync() { await _service.SaveAsync(); },"private async void OnSaveClick(object s, RoutedEventArgs e) { await _service.SaveAsync(); }",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/asyncrelaycommand
30,Commands,Use CommandParameter for context,Pass data from the UI element to the command handler,CommandParameter for item-specific actions,Relying on SelectedItem in every command,"<Button Command=""{Binding DeleteCommand}"" CommandParameter=""{Binding}""/>","Command handler accessing SelectedItem directly",Low,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/commanding-overview
31,Commands,Use InputBindings for keyboard shortcuts,Bind keyboard gestures to commands without manual key handling,KeyBinding inside Window.InputBindings,Custom key handling in PreviewKeyDown,"<Window.InputBindings><KeyBinding Key=""S"" Modifiers=""Ctrl"" Command=""{Binding SaveCommand}""/></Window.InputBindings>",PreviewKeyDown handler checking for Ctrl+S,Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/commanding-overview
32,Performance,Use VirtualizingStackPanel for large lists,Only creates UI elements for visible items. ListBox/ListView virtualize by default; TreeView requires opt-in,VirtualizingStackPanel.IsVirtualizing=True (set on TreeView; default for ListBox),Disabling virtualization on long lists,"<TreeView VirtualizingStackPanel.IsVirtualizing=""True"" VirtualizingStackPanel.VirtualizationMode=""Recycling""/>","<ListBox ScrollViewer.CanContentScroll=""False""/>",High,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/optimizing-performance-controls
33,Performance,Freeze Freezable objects,Frozen brushes and geometries skip change tracking,Freeze brushes and pens that do not change,Mutable brushes used as static resources,"var brush = new SolidColorBrush(Colors.Blue); brush.Freeze();","new SolidColorBrush() without Freeze in resources",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/freezable-objects-overview
34,Performance,Use DependencyProperty for custom-control binding targets,Binding target properties on custom controls must be DependencyProperties (sources can be plain CLR properties with INPC),Define DependencyProperty for properties bound TO on a custom control,Plain CLR properties as binding targets on custom controls,"public static readonly DependencyProperty NameProperty = ...","public string Name { get; set; } as binding target on custom control",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/properties/dependency-properties-overview
35,Performance,Use async for long operations,Keep UI thread responsive,async/await with Task.Run for CPU work,Synchronous operations that freeze the UI,"await Task.Run(() => HeavyComputation());","HeavyComputation() on UI thread",High,https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/
36,Performance,Profile with PerfView and Visual Studio,Measure before optimizing,Visual Studio diagnostic tools and PerfView,Guessing at performance bottlenecks,Performance Profiler in Visual Studio (Alt+F2),Optimize without profiling,Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/optimizing-wpf-application-performance
37,Threading,Use Dispatcher for UI updates,UI elements can only be accessed from the UI thread,Dispatcher.Invoke or BeginInvoke from background threads,Accessing UI elements from background threads,"Application.Current.Dispatcher.Invoke(() => Status = ""Done"");","textBlock.Text = ""Done"" from Task.Run",High,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/threading-model
38,Threading,Prefer async/await over Dispatcher,Modern async code returns to UI context automatically,async/await which resumes on captured SynchronizationContext,Manual Dispatcher.BeginInvoke for every callback,"var data = await LoadDataAsync(); Items = data;","Dispatcher.BeginInvoke(() => Items = result) in callback",Medium,https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/
39,Threading,Use Task.Run for CPU-bound work,Offload intensive work from UI thread,Task.Run for compute-bound work,Long-running computations on UI thread,"var result = await Task.Run(() => Compute());","var result = Compute(); on UI thread",High,https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming
40,Threading,Report progress from background tasks,Update UI with progress during long operations,IProgress<T> with Task.Run,Polling a shared variable for progress,"var progress = new Progress<int>(p => ProgressBar.Value = p); await Task.Run(() => Work(progress));","while (!done) { Thread.Sleep(100); check shared int; }",Medium,https://learn.microsoft.com/en-us/dotnet/api/system.progress-1
41,Threading,Handle DispatcherUnhandledException,Catch unhandled UI-thread exceptions to log them and prevent the default WPF crash dialog,Subscribe in App.xaml or App.OnStartup and set e.Handled=true after logging,Letting WPF show its default crash dialog and silently shut down,"<Application DispatcherUnhandledException=""App_OnUnhandledException"">",No global handler so any unhandled exception crashes the app,High,https://learn.microsoft.com/en-us/dotnet/api/system.windows.application.dispatcherunhandledexception
42,Accessibility,Set AutomationProperties,Enable screen reader support,AutomationProperties.Name on interactive controls,Controls without automation names,"<Button AutomationProperties.Name=""Save document""/>","<Button><Image Source=""save.png""/></Button> without name",High,https://learn.microsoft.com/en-us/dotnet/api/system.windows.automation.automationproperties
43,Accessibility,Support keyboard navigation,All functionality reachable via keyboard,Tab order and KeyboardNavigation properties,Mouse-only interactions,"<StackPanel KeyboardNavigation.TabNavigation=""Cycle"">","Click handlers with no keyboard equivalent",High,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/focus-overview
44,Accessibility,Support high contrast themes,Respect Windows high contrast settings,SystemColors and SystemFonts resources,Hardcoded colors that disappear in high contrast,"Foreground=""{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}""","Foreground=""#333333"" everywhere",Medium,https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/accessibility-best-practices
45,Accessibility,Use appropriate control types,Semantic controls convey role to assistive tech,Button for actions CheckBox for toggles,Styled TextBlock with click handler as fake button,"<Button Content=""Submit""/>","<TextBlock MouseDown=""OnSubmitClick"" Text=""Submit""/>",High,https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/accessibility-best-practices
46,Accessibility,Support DPI scaling,Ensure UI is crisp at all display scale factors,Device-independent units and vector graphics,Pixel-based bitmaps that blur at high DPI,"<Path Data=""M 10,10 L 20,20""/> or DrawingImage","<Image Source=""icon_32x32.png""/> at 200% scaling",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/graphics-multimedia/graphics
47,Accessibility,Declare PerMonitorV2 DPI awareness,WPF defaults to System-DPI-aware unless you opt into PerMonitorV2 via app.manifest,app.manifest with dpiAwareness PerMonitorV2,Default System DPI awareness for Windows 10/11 apps,"<dpiAwareness xmlns=""http://schemas.microsoft.com/SMI/2016/WindowsSettings"">PerMonitorV2</dpiAwareness>",No app.manifest leaving app at System DPI,Medium,https://learn.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
48,Architecture,Use MVVM pattern,Separate View ViewModel and Model concerns,MVVM with data binding and commands,Logic in code-behind,ViewModel with INotifyPropertyChanged and ICommand,MainWindow.xaml.cs with all business logic,High,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
49,Architecture,Override App.OnStartup for app initialization,Wire DI build the host resolve MainWindow and parse command-line args in OnStartup,Override OnStartup when DI or argument parsing is needed,Relying on StartupUri when MainWindow needs constructor injection,protected override void OnStartup(StartupEventArgs e) { _host.Start(); _host.Services.GetRequiredService<MainWindow>().Show(); },"<Application StartupUri=""MainWindow.xaml""/> when MainWindow has constructor dependencies",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/app-development/application-management-overview
50,Architecture,Use dependency injection,Wire Microsoft.Extensions.Hosting Generic Host in App.OnStartup and resolve ViewModels from the container,Generic Host with Microsoft.Extensions.DependencyInjection,new Service() in ViewModel constructors,"services.AddTransient<MainViewModel>();","new MainViewModel(new DataService()) in App.xaml.cs",Medium,https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection/overview
51,Architecture,Use CommunityToolkit.Mvvm,Source generators reduce MVVM boilerplate,[ObservableProperty] and [RelayCommand] attributes,Hand-written INotifyPropertyChanged for every property,"[ObservableProperty] private string _name;","private string _name; public string Name { get ... set ... OnPropertyChanged ... }",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
52,Architecture,Keep code-behind minimal,Code-behind should only contain view-specific logic,View logic like focus management and animations in code-behind,Business logic and data access in code-behind,Loaded handler that sets initial focus,Loaded handler that calls database and populates grid,Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/xaml/
53,Architecture,Use messaging for loose coupling,Communicate between ViewModels without references,WeakReferenceMessenger from CommunityToolkit.Mvvm,Direct ViewModel-to-ViewModel references,"WeakReferenceMessenger.Default.Send(new ItemSavedMessage(item));","MainViewModel.Instance.RefreshItems() from DetailViewModel",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/messenger
54,Testing,Unit test ViewModels,Test business logic independent of UI,xUnit or NUnit tests on ViewModel methods and properties,Manual testing through the UI only,"[Fact] public void Save_WhenValid_SetsIsBusy() { vm.Save(); Assert.True(vm.IsBusy); }","Clicking buttons in the running app to verify",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
55,Testing,Mock services in tests,Isolate ViewModel from external dependencies,Moq or NSubstitute for service interfaces,Real database calls in unit tests,"var mock = new Mock<IDataService>(); var vm = new MainViewModel(mock.Object);","new MainViewModel(new SqlDataService()) in tests",Medium,https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
56,Testing,Use UI Automation for integration tests,Automated UI testing with Microsoft UI Automation,FlaUI or Appium 2 (appium-windows-driver) for end-to-end tests,Manual regression testing only,"AutomationElement.FindFirst(TreeScope.Children, condition)",Manual click-through testing,Medium,https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/ui-automation-overview
Can't render this file because it contains an unexpected character in line 2 and column 234.

67
scripts/smoke-stacks.sh Executable file
View File

@@ -0,0 +1,67 @@
#!/usr/bin/env bash
# Smoke test: every stack registered in STACK_CONFIG must return at least one
# search result for a neutral query. Catches registry/CSV regressions early
# (e.g. a stack added to STACK_CONFIG but missing its CSV, or a CSV emptied
# by a botched merge).
#
# Usage: scripts/smoke-stacks.sh [query]
# Env: EXPECTED_STACK_COUNT — default 22. Bump deliberately when adding
# or removing a stack so accidental drift still fails loudly.
#
# Exit codes:
# 0 — all stacks returned ≥1 result
# 1 — at least one stack returned 0 results
# 2 — environment problem (search.py missing, registry size mismatch)
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SCRIPTS_DIR="$REPO_ROOT/src/ui-ux-pro-max/scripts"
SEARCH="$SCRIPTS_DIR/search.py"
QUERY="${1:-performance}"
EXPECTED_COUNT="${EXPECTED_STACK_COUNT:-22}"
if [ ! -f "$SEARCH" ]; then
echo "FAIL: search.py not found at $SEARCH" >&2
exit 2
fi
# Single source of truth: pull stacks from STACK_CONFIG so this script never
# goes stale relative to the registry.
STACKS=()
while IFS= read -r line; do
line="${line%$'\r'}" # strip CR on Windows where python's print emits CRLF
[ -n "$line" ] && STACKS+=("$line")
done < <(PYTHONPATH="$SCRIPTS_DIR" python3 -c "
from core import AVAILABLE_STACKS
for s in AVAILABLE_STACKS:
print(s)
")
if [ "${#STACKS[@]}" -ne "$EXPECTED_COUNT" ]; then
echo "FAIL: STACK_CONFIG has ${#STACKS[@]} stacks, expected $EXPECTED_COUNT" >&2
echo " Set EXPECTED_STACK_COUNT to override after an intentional change." >&2
exit 2
fi
echo "Smoke-testing ${#STACKS[@]} stacks with query '$QUERY':"
fail=0
for s in "${STACKS[@]}"; do
count=$(python3 "$SEARCH" "$QUERY" --stack "$s" -n 1 --json 2>/dev/null \
| python3 -c "import json,sys; print(json.load(sys.stdin).get('count',0))")
if [ "${count:-0}" -gt 0 ]; then
printf ' PASS %-18s %d\n' "$s" "$count"
else
printf ' FAIL %-18s 0\n' "$s"
fail=$((fail + 1))
fi
done
total=${#STACKS[@]}
echo
if [ "$fail" -gt 0 ]; then
echo "FAIL: $fail/$total stacks returned 0 results for '$QUERY'" >&2
exit 1
fi
echo "OK: $total/$total stacks returned ≥1 result"

View File

@@ -0,0 +1,57 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,XAML,Use Avalonia XAML namespace,Avalonia has its own XAML namespace not WPF,xmlns= for Avalonia-specific namespace,WPF xmlns or UWP xmlns,"<Window xmlns=""https://github.com/avaloniaui"">","<Window xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">",High,https://docs.avaloniaui.net/docs/fundamentals/avalonia-xaml
2,XAML,Use compiled bindings with x:DataType,Enable compile-time binding validation,x:DataType on root or DataTemplate for compiled bindings,Reflection-based bindings in production,"<Window x:DataType=""vm:MainViewModel""><TextBlock Text=""{Binding Name}""/></Window>","<Window><TextBlock Text=""{Binding Name}""/> without x:DataType",High,https://docs.avaloniaui.net/docs/data-binding/compiled-bindings
3,XAML,Enable compiled bindings globally,AvaloniaUseCompiledBindingsByDefault in csproj makes every binding require x:DataType and is required for trim-safe Native AOT,AvaloniaUseCompiledBindingsByDefault MSBuild property in csproj,Relying on runtime binding resolution,"<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>","No compiled binding enforcement",High,https://docs.avaloniaui.net/docs/data-binding/compiled-bindings
4,XAML,Use #name shorthand for element-to-element bindings,Compiled bindings cannot resolve {Binding ElementName=...} - use the #name shorthand which relies on NameScope lookup,#name shorthand referencing x:Name controls in the same NameScope,ElementName binding inside a compiled-binding scope,"<TextBlock Text=""{Binding #SearchBox.Text}""/>","<TextBlock Text=""{Binding ElementName=SearchBox, Path=Text}""/> under compiled bindings",Medium,https://docs.avaloniaui.net/docs/data-binding/compiled-bindings
5,Styling,Use CSS-like selectors,Avalonia uses selectors not implicit styles,Selectors targeting control types classes and pseudoclasses,WPF-style implicit Style with TargetType,"<Style Selector=""Button.primary""><Setter Property=""Background"" Value=""Blue""/></Style>","<Style TargetType=""Button""> without Selector",High,https://docs.avaloniaui.net/docs/styling/selectors
6,Styling,Use pseudoclass selectors for states,Target control states with colon syntax,:pointerover :pressed :focus for interactive states,VisualStateManager or Triggers,"<Style Selector=""Button:pointerover""><Setter Property=""Opacity"" Value=""0.8""/></Style>","<VisualStateManager> for hover effects",Medium,https://docs.avaloniaui.net/docs/styling/pseudoclasses
7,Styling,Use nesting selectors,Child and descendant combinators for scoped styles,> for direct child and space for descendant,Flat selectors that match too broadly,"<Style Selector=""StackPanel > Button""><Setter Property=""Margin"" Value=""4""/></Style>","<Style Selector=""Button""> that affects all buttons unintentionally",Medium,https://docs.avaloniaui.net/docs/styling/style-selector-syntax
8,Styling,Use StyleInclude for modularity,Split styles into separate AXAML files,StyleInclude to import themed resource files,All styles in a single monolithic App.axaml,"<StyleInclude Source=""/Styles/ButtonStyles.axaml""/>","1000+ line App.axaml with all styles",Medium,https://docs.avaloniaui.net/docs/styling/styles
9,Styling,Use Fluent or Simple theme,Built-in Avalonia themes,FluentTheme or SimpleTheme as base,Custom theme from scratch,"<FluentTheme/>","Building all control templates manually",High,https://docs.avaloniaui.net/docs/styling/themes
10,Styling,Use theme variants for dark mode,Switch between light and dark,RequestedThemeVariant for theme switching,"Hardcoded colors ignoring theme variants","Application.Current.RequestedThemeVariant = ThemeVariant.Dark;","Manually changing every brush for dark mode",Medium,https://docs.avaloniaui.net/docs/styling/themes
11,Controls,Use DataGrid for tabular data,DataGrid is a separate Avalonia.Controls.DataGrid NuGet package and requires its theme StyleInclude in App.axaml,DataGrid after adding package and StyleInclude for the matching theme,Custom 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)",Medium,https://docs.avaloniaui.net/docs/reference/controls/datagrid/
12,Controls,Use TreeView with TreeDataTemplate,Avalonia uses TreeDataTemplate for hierarchical data - HierarchicalDataTemplate is WPF only,TreeDataTemplate inside TreeView.ItemTemplate with ItemsSource pointing at child collection,HierarchicalDataTemplate 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 Avalonia",High,https://docs.avaloniaui.net/docs/reference/controls/treeview-1
13,Controls,Use NativeMenu for platform menus,Native menu bar on macOS and desktop,NativeMenu for cross-platform menu bar,Custom menu implementation per platform,"<NativeMenu.Menu><NativeMenu><NativeMenuItem Header=""File""/></NativeMenu></NativeMenu.Menu>","Custom menu bar control for each platform",Medium,https://docs.avaloniaui.net/docs/reference/controls/nativemenu
14,Data Binding,Implement INotifyPropertyChanged,Standard .NET property notification,INotifyPropertyChanged or CommunityToolkit.Mvvm,Properties without change notification,"[ObservableProperty] private string _name;","public string Name { get; set; } without notification",High,https://docs.avaloniaui.net/docs/data-binding/inotifypropertychanged
15,Data Binding,Use ObservableCollection for lists,UI updates on collection changes,ObservableCollection<T> for bound collections,List<T> for ItemsSources,"ObservableCollection<Item> Items { get; } = new();","List<Item> Items { get; set; }",High,https://docs.avaloniaui.net/docs/data-binding/inotifypropertychanged
16,Data Binding,Use binding to named controls,Element-to-element binding with # syntax,#ElementName.Property for cross-element binding,Code-behind for element references,"<TextBlock Text=""{Binding #slider.Value, StringFormat='{}{0:F0}'}""/>","Code-behind ValueChanged handler to update TextBlock",Medium,https://docs.avaloniaui.net/docs/data-binding/introduction-to-data-binding
17,Data Binding,Use converters or FuncValueConverter,Transform data for display,FuncValueConverter for simple inline conversions,Complex IValueConverter classes for trivial transforms,"public static FuncValueConverter<bool, IBrush> BoolToColor = new(b => b ? Brushes.Green : Brushes.Red);","Full IValueConverter class for bool to color",Medium,https://docs.avaloniaui.net/docs/data-binding/how-to-create-a-custom-data-binding-converter
18,Cross-Platform,Use platform-specific code carefully,Isolate platform code behind abstractions,Interface + platform implementation pattern,#if directives scattered through ViewModels,"IPlatformService with platform-specific implementations","#if WINDOWS ... #elif LINUX ... in ViewModel",Medium,https://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/
19,Cross-Platform,Test on all target platforms,Rendering and behavior varies across platforms,CI testing on Windows macOS and Linux,Testing only on development platform,"GitHub Actions matrix with windows-latest ubuntu-latest macos-latest","Testing only on Windows assuming cross-platform works",High,https://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/
20,Cross-Platform,Handle platform file paths,Path separators differ across OS,Path.Combine and Environment.SpecialFolder,Hardcoded backslashes or forward slashes,"Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), ""MyApp"")","@""C:\Users\data\config.json""",Medium,https://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/dealing-with-platforms
21,Cross-Platform,Use Avalonia asset system,Platform-agnostic resource loading,avares:// URI scheme for embedded resources,File system paths for assets,"<Image Source=""avares://MyApp/Assets/logo.png""/>","<Image Source=""C:/images/logo.png""/>",High,https://docs.avaloniaui.net/docs/fundamentals/including-assets
22,Performance,Use virtualization for large lists,Only render visible items,ListBox and ItemsRepeater with virtualization,Non-virtualizing ItemsControl for large lists,"<ListBox ItemsSource=""{Binding LargeList}""/>","<ItemsControl><StackPanel> for 10K items",High,https://docs.avaloniaui.net/docs/reference/controls/listbox
23,Performance,Avoid unnecessary bindings,Each binding has overhead,Bind only properties that change,Binding static labels and headers,"<TextBlock Text=""{Binding DynamicTitle}""/> but static: <TextBlock Text=""Settings""/>","<TextBlock Text=""{Binding SettingsLabel}""/> for constant string",Low,https://docs.avaloniaui.net/docs/data-binding/introduction-to-data-binding
24,Performance,Set bitmap interpolation mode on scaled images,RenderOptions.BitmapInterpolationMode controls image scaling quality vs cost; default may look aliased on upscaled or downscaled bitmaps,RenderOptions.SetBitmapInterpolationMode tuned to the use case,Default interpolation on scaled images that look blurry or aliased,"RenderOptions.SetBitmapInterpolationMode(image, BitmapInterpolationMode.HighQuality);","Image scaled with Stretch and no interpolation hint set",Low,https://docs.avaloniaui.net/docs/concepts/image-interpolation
25,Performance,Profile with Avalonia DevTools,Built-in diagnostic tools,DevTools for visual tree and binding inspection,Console.WriteLine debugging,Attach DevTools in debug mode with F12,Print statements to debug layout issues,Medium,https://docs.avaloniaui.net/docs/guides/implementation-guides/developer-tools
26,Architecture,Use MVVM with ReactiveUI or CommunityToolkit,Proven MVVM frameworks for Avalonia,ReactiveUI or CommunityToolkit.Mvvm for ViewModels,Code-behind for all logic,"public class MainViewModel : ReactiveObject { }","MainWindow.axaml.cs with all business logic",High,https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/
27,Architecture,Use ViewLocator pattern,Convention-based View-ViewModel resolution,ViewLocator for automatic view resolution,Manual view instantiation and DataContext wiring,"class ViewLocator : IDataTemplate { Build(object data) => new MainView(); }","new MainView { DataContext = new MainViewModel() } everywhere",Medium,https://docs.avaloniaui.net/docs/data-templates/view-locator
28,Architecture,Use dependency injection,Register services in a Microsoft.Extensions.DependencyInjection container during startup before any view is constructed - resolve ViewModels through the provider not via a static ServiceLocator,Build the ServiceProvider in BuildAvaloniaApp or OnFrameworkInitializationCompleted then resolve ViewModels from it,Static ServiceLocator or new-ing ViewModels inline in code-behind,"services.AddSingleton<IDataService, DataService>(); services.AddTransient<MainViewModel>(); var provider = services.BuildServiceProvider(); // wired before windows are created","ServiceLocator.Current.GetInstance<IDataService>() called from random ViewModels with no registration ordering",Medium,https://docs.avaloniaui.net/docs/app-development/dependency-injection
29,Architecture,Separate Views from ViewModels,Keep UI and logic in separate projects,ViewModels in a separate class library,ViewModels in the same project referencing Avalonia types,"MyApp.Core (no Avalonia refs) + MyApp.Desktop (Avalonia views)","ViewModel importing Avalonia.Controls",Medium,https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/
30,Accessibility,Set AutomationProperties,Enable screen reader support,AutomationProperties.Name on interactive controls,Controls without accessible names,"<Button AutomationProperties.Name=""Close dialog""><PathIcon Data=""...""/></Button>","<Button><PathIcon/></Button> without accessible name",High,https://docs.avaloniaui.net/api/avalonia/automation/automationproperties
31,Accessibility,Support keyboard navigation,Full keyboard operability,TabIndex and KeyboardNavigation properties,Mouse-only interactions,"<Button TabIndex=""1"" Content=""Save""/>","Clickable controls without keyboard support",High,https://docs.avaloniaui.net/docs/input-interaction/keyboard-and-hotkeys
32,Accessibility,Use semantic control types,Controls convey meaning to assistive tech,Button for actions ListBox for selection,TextBlock with PointerPressed as fake button,"<Button Content=""Submit""/>","<TextBlock PointerPressed=""OnSubmitClick"" Text=""Submit""/>",High,https://docs.avaloniaui.net/docs/reference/controls/
33,Testing,Use Avalonia.Headless for UI tests,Run UI tests without display server,Avalonia.Headless for CI-compatible UI testing,Skipping UI tests in CI,"[AvaloniaTest] public void Button_Click_Updates_Label() { ... }","UI tests that require a display server",Medium,https://docs.avaloniaui.net/docs/concepts/headless/
34,Testing,Unit test ViewModels,Test business logic independently,xUnit or NUnit on ViewModel methods,Testing through UI only,"[Fact] public void AddItem_IncreasesCount() { vm.AddItem(); Assert.Equal(1, vm.Items.Count); }","Manual testing by running the app",Medium,https://docs.avaloniaui.net/docs/concepts/headless/
35,Testing,Test converters independently,Value converters contain testable logic,Unit tests on Convert and ConvertBack,Assuming converters work without tests,"[Fact] public void BoolToColor_True_ReturnsGreen() { Assert.Equal(Brushes.Green, converter.Convert(true)); }","No converter tests",Low,https://docs.avaloniaui.net/docs/data-binding/how-to-create-a-custom-data-binding-converter
36,Navigation,Use ReactiveUI routing for navigation,IScreen and RoutingState for page navigation,ReactiveUI RoutingState with IScreen on main ViewModel,Manual content swapping in code-behind,"public RoutingState Router { get; } = new(); Router.Navigate.Execute(new DetailViewModel());","contentControl.Content = new DetailView(); in code-behind",Medium,https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/routing
37,Navigation,Use UserControl for views,Pages and screens should be UserControls hosted in a ContentControl,UserControl for each view with RoutedViewHost or ContentControl,Window per page or nested Windows,"<UserControl x:Class=""MyApp.Views.DetailView"">","new Window() for each page in the app",Medium,https://docs.avaloniaui.net/docs/custom-controls/
38,Navigation,Use page transitions for view switching,Built-in transitions for smooth navigation,CrossFade PageSlide or CompositePageTransition declared as a property element,Abrupt 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 views",Low,https://docs.avaloniaui.net/docs/reference/controls/transitioningcontentcontrol
39,Navigation,Support back navigation,Maintain navigation history for complex apps,Router.NavigateBack or custom back stack,No way to return to previous views,"<Button Command=""{Binding Router.NavigateBack}"" Content=""Back""/>","Single-direction navigation with no back support",Medium,https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/routing
40,Controls,Use AutoCompleteBox for search,Built-in autocomplete and suggestion control,AutoCompleteBox with FilterMode and ItemsSource,TextBox with manual Popup and ListBox for suggestions,"<AutoCompleteBox ItemsSource=""{Binding Suggestions}"" FilterMode=""Contains""/>","TextBox with custom Popup for autocomplete",Medium,https://docs.avaloniaui.net/docs/reference/controls/autocompletebox
41,Controls,Use TabControl for tabbed interfaces,Standard tabbed navigation and content switching,TabControl with TabItem for tabbed layouts,Manual toggle buttons swapping content,"<TabControl><TabItem Header=""General""><GeneralView/></TabItem><TabItem Header=""Advanced""><AdvancedView/></TabItem></TabControl>","ToggleButtons with manual content switching logic",Medium,https://docs.avaloniaui.net/docs/reference/controls/tabcontrol
42,Controls,Use SplitView for master-detail,Collapsible pane layout for navigation or panels,SplitView with Pane and Content areas,Manual 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 sidebar",Medium,https://docs.avaloniaui.net/docs/reference/controls/splitview
43,Controls,Use Flyout for contextual actions,Attach popup menus and actions to controls,Flyout and MenuFlyout on Button or other controls,Custom 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 positioning",Medium,https://docs.avaloniaui.net/docs/reference/controls/flyouts
44,Lifecycle,Use AppBuilder for app configuration,Configure platform features and services at startup,AppBuilder with UsePlatformDetect and fluent API,Manual platform initialization,"AppBuilder.Configure<App>().UsePlatformDetect().WithInterFont().StartWithClassicDesktopLifetime(args);","Manual platform-specific startup code per OS",High,https://docs.avaloniaui.net/docs/fundamentals/application-lifetimes
45,Lifecycle,Initialize MainWindow in OnFrameworkInitializationCompleted,Override 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 ready,Override OnFrameworkInitializationCompleted and pattern-match on IClassicDesktopStyleApplicationLifetime for desktop-only setup,Creating windows in the App constructor or assuming the same lifetime type on every platform,"public 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 type",High,https://docs.avaloniaui.net/docs/fundamentals/application-lifetimes
46,Animation,Use CSS-like keyframe animations,Avalonia supports declarative animations in XAML and code,Animation with KeyFrame and Setter for property animations,Manual timer-based property updates,"<Border.Transitions><DoubleTransition Property=""Opacity"" Duration=""0:0:0.3""/></Border.Transitions>","DispatcherTimer ticking to update Opacity manually",Medium,https://docs.avaloniaui.net/docs/graphics-animation/animations
47,Animation,Use Transitions for implicit animations,Automatic animation when property values change,Transitions collection on controls for smooth changes,Instant property changes with no visual feedback,"<Button.Transitions><TransformOperationsTransition Property=""RenderTransform"" Duration=""0:0:0.2""/></Button.Transitions>","Direct property set with no transition",Low,https://docs.avaloniaui.net/docs/graphics-animation/control-transitions
48,Performance,Use compiled bindings and TrimmerRoots.xml for PublishAot,Avalonia 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 them,x:CompileBindings=True on every view plus TrimmerRoots.xml for runtime-resolved types,PublishAot 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 configuration",Medium,https://docs.avaloniaui.net/docs/deployment/native-aot
49,Threading,Marshal cross-thread work to the UI thread,Avalonia controls and bound properties are not thread-safe and touching them off the UI thread throws InvalidOperationException,Dispatcher.UIThread.Post or InvokeAsync to bounce work back to the UI thread,Direct property writes from Task.Run or background threads,"await Dispatcher.UIThread.InvokeAsync(() => Status = ""Done"");","Task.Run(() => { Status = ""Done""; }); // throws Call from invalid thread",High,https://docs.avaloniaui.net/docs/app-development/threading
50,Commands,Use AsyncRelayCommand or ReactiveCommand for async work,Async-aware commands disable themselves while running and surface CancellationToken so users cannot double-invoke a long operation,[RelayCommand] async Task method or ReactiveCommand.CreateFromTask,async 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(); }",High,https://docs.avaloniaui.net/docs/input-interaction/commanding
51,Styling,Use DynamicResource for theme-aware brushes,ResourceDictionary.ThemeDictionaries entries must be looked up via DynamicResource - StaticResource resolves once at load and won't update when the active theme variant changes,DynamicResource for brushes and colors that follow the active theme variant,Hardcoded 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 variants",Medium,https://docs.avaloniaui.net/docs/app-development/resource-dictionary
52,Input,Use HotKey or KeyBinding for keyboard shortcuts,Built-in HotKey on ICommandSource and Window.KeyBindings handle modifier keys focus scoping and cross-platform Ctrl/Cmd mapping,HotKey on a command-bound control or KeyBinding on the Window,Manual KeyDown handlers checking Key and KeyModifiers,"<Button Command=""{Binding SaveCommand}"" HotKey=""Ctrl+S"" Content=""Save""/>","OnKeyDown checking e.Key == Key.S && e.KeyModifiers == KeyModifiers.Control",Medium,https://docs.avaloniaui.net/docs/input-interaction/mouse-and-keyboard-shortcuts
53,Windowing,Customize window chrome with ExtendClientAreaToDecorationsHint,Set ExtendClientAreaToDecorationsHint to extend content into the title bar area and tag a region with WindowDecorationProperties.ElementRole=TitleBar to keep native drag and maximize behavior,ExtendClientAreaToDecorationsHint plus a region tagged ElementRole=TitleBar,SystemDecorations=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-behind",Medium,https://docs.avaloniaui.net/docs/app-development/window-management
54,Storage,Use TopLevel.StorageProvider for file pickers,The legacy OpenFileDialog/SaveFileDialog APIs are obsolete in Avalonia 11 - use TopLevel.GetTopLevel(this).StorageProvider with OpenFilePickerAsync/SaveFilePickerAsync/OpenFolderPickerAsync which returns IStorageFile/IStorageFolder and works on desktop mobile and browser,TopLevel.StorageProvider with OpenFilePickerAsync and FilePickerOpenOptions,OpenFileDialog or SaveFileDialog from older Avalonia samples or copied from WPF,"var 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 API",High,https://docs.avaloniaui.net/docs/concepts/services/storage-provider/
55,Windowing,Use TrayIcon for system tray icon,TrayIcon 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 desktops,TrayIcon with NativeMenu inside TrayIcon.Icons on the Application,Custom 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/Invoke",Medium,https://docs.avaloniaui.net/docs/controls/tray-icon
56,Cross-Platform,Use OnPlatform and OnFormFactor markup for per-OS values,OnPlatform 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 sizes,OnPlatform with Default Windows macOS Linux entries directly in the property setter,RuntimeInformation.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()) ...",Medium,https://docs.avaloniaui.net/docs/platform-specific-guides/xaml
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 XAML Use Avalonia XAML namespace Avalonia has its own XAML namespace not WPF xmlns= for Avalonia-specific namespace WPF xmlns or UWP xmlns <Window xmlns="https://github.com/avaloniaui"> <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> High https://docs.avaloniaui.net/docs/fundamentals/avalonia-xaml
3 2 XAML Use compiled bindings with x:DataType Enable compile-time binding validation x:DataType on root or DataTemplate for compiled bindings Reflection-based bindings in production <Window x:DataType="vm:MainViewModel"><TextBlock Text="{Binding Name}"/></Window> <Window><TextBlock Text="{Binding Name}"/> without x:DataType High https://docs.avaloniaui.net/docs/data-binding/compiled-bindings
4 3 XAML Enable compiled bindings globally AvaloniaUseCompiledBindingsByDefault in csproj makes every binding require x:DataType and is required for trim-safe Native AOT AvaloniaUseCompiledBindingsByDefault MSBuild property in csproj Relying on runtime binding resolution <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault> No compiled binding enforcement High https://docs.avaloniaui.net/docs/data-binding/compiled-bindings
5 4 XAML Use #name shorthand for element-to-element bindings Compiled bindings cannot resolve {Binding ElementName=...} - use the #name shorthand which relies on NameScope lookup #name shorthand referencing x:Name controls in the same NameScope ElementName binding inside a compiled-binding scope <TextBlock Text="{Binding #SearchBox.Text}"/> <TextBlock Text="{Binding ElementName=SearchBox, Path=Text}"/> under compiled bindings Medium https://docs.avaloniaui.net/docs/data-binding/compiled-bindings
6 5 Styling Use CSS-like selectors Avalonia uses selectors not implicit styles Selectors targeting control types classes and pseudoclasses WPF-style implicit Style with TargetType <Style Selector="Button.primary"><Setter Property="Background" Value="Blue"/></Style> <Style TargetType="Button"> without Selector High https://docs.avaloniaui.net/docs/styling/selectors
7 6 Styling Use pseudoclass selectors for states Target control states with colon syntax :pointerover :pressed :focus for interactive states VisualStateManager or Triggers <Style Selector="Button:pointerover"><Setter Property="Opacity" Value="0.8"/></Style> <VisualStateManager> for hover effects Medium https://docs.avaloniaui.net/docs/styling/pseudoclasses
8 7 Styling Use nesting selectors Child and descendant combinators for scoped styles > for direct child and space for descendant Flat selectors that match too broadly <Style Selector="StackPanel > Button"><Setter Property="Margin" Value="4"/></Style> <Style Selector="Button"> that affects all buttons unintentionally Medium https://docs.avaloniaui.net/docs/styling/style-selector-syntax
9 8 Styling Use StyleInclude for modularity Split styles into separate AXAML files StyleInclude to import themed resource files All styles in a single monolithic App.axaml <StyleInclude Source="/Styles/ButtonStyles.axaml"/> 1000+ line App.axaml with all styles Medium https://docs.avaloniaui.net/docs/styling/styles
10 9 Styling Use Fluent or Simple theme Built-in Avalonia themes FluentTheme or SimpleTheme as base Custom theme from scratch <FluentTheme/> Building all control templates manually High https://docs.avaloniaui.net/docs/styling/themes
11 10 Styling Use theme variants for dark mode Switch between light and dark RequestedThemeVariant for theme switching Hardcoded colors ignoring theme variants Application.Current.RequestedThemeVariant = ThemeVariant.Dark; Manually changing every brush for dark mode Medium https://docs.avaloniaui.net/docs/styling/themes
12 11 Controls Use DataGrid for tabular data DataGrid is a separate Avalonia.Controls.DataGrid NuGet package and requires its theme StyleInclude in App.axaml DataGrid after adding package and StyleInclude for the matching theme Custom 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) Medium https://docs.avaloniaui.net/docs/reference/controls/datagrid/
13 12 Controls Use TreeView with TreeDataTemplate Avalonia uses TreeDataTemplate for hierarchical data - HierarchicalDataTemplate is WPF only TreeDataTemplate inside TreeView.ItemTemplate with ItemsSource pointing at child collection HierarchicalDataTemplate 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 Avalonia High https://docs.avaloniaui.net/docs/reference/controls/treeview-1
14 13 Controls Use NativeMenu for platform menus Native menu bar on macOS and desktop NativeMenu for cross-platform menu bar Custom menu implementation per platform <NativeMenu.Menu><NativeMenu><NativeMenuItem Header="File"/></NativeMenu></NativeMenu.Menu> Custom menu bar control for each platform Medium https://docs.avaloniaui.net/docs/reference/controls/nativemenu
15 14 Data Binding Implement INotifyPropertyChanged Standard .NET property notification INotifyPropertyChanged or CommunityToolkit.Mvvm Properties without change notification [ObservableProperty] private string _name; public string Name { get; set; } without notification High https://docs.avaloniaui.net/docs/data-binding/inotifypropertychanged
16 15 Data Binding Use ObservableCollection for lists UI updates on collection changes ObservableCollection<T> for bound collections List<T> for ItemsSources ObservableCollection<Item> Items { get; } = new(); List<Item> Items { get; set; } High https://docs.avaloniaui.net/docs/data-binding/inotifypropertychanged
17 16 Data Binding Use binding to named controls Element-to-element binding with # syntax #ElementName.Property for cross-element binding Code-behind for element references <TextBlock Text="{Binding #slider.Value, StringFormat='{}{0:F0}'}"/> Code-behind ValueChanged handler to update TextBlock Medium https://docs.avaloniaui.net/docs/data-binding/introduction-to-data-binding
18 17 Data Binding Use converters or FuncValueConverter Transform data for display FuncValueConverter for simple inline conversions Complex IValueConverter classes for trivial transforms public static FuncValueConverter<bool, IBrush> BoolToColor = new(b => b ? Brushes.Green : Brushes.Red); Full IValueConverter class for bool to color Medium https://docs.avaloniaui.net/docs/data-binding/how-to-create-a-custom-data-binding-converter
19 18 Cross-Platform Use platform-specific code carefully Isolate platform code behind abstractions Interface + platform implementation pattern #if directives scattered through ViewModels IPlatformService with platform-specific implementations #if WINDOWS ... #elif LINUX ... in ViewModel Medium https://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/
20 19 Cross-Platform Test on all target platforms Rendering and behavior varies across platforms CI testing on Windows macOS and Linux Testing only on development platform GitHub Actions matrix with windows-latest ubuntu-latest macos-latest Testing only on Windows assuming cross-platform works High https://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/
21 20 Cross-Platform Handle platform file paths Path separators differ across OS Path.Combine and Environment.SpecialFolder Hardcoded backslashes or forward slashes Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MyApp") @"C:\Users\data\config.json" Medium https://docs.avaloniaui.net/docs/guides/building-cross-platform-applications/dealing-with-platforms
22 21 Cross-Platform Use Avalonia asset system Platform-agnostic resource loading avares:// URI scheme for embedded resources File system paths for assets <Image Source="avares://MyApp/Assets/logo.png"/> <Image Source="C:/images/logo.png"/> High https://docs.avaloniaui.net/docs/fundamentals/including-assets
23 22 Performance Use virtualization for large lists Only render visible items ListBox and ItemsRepeater with virtualization Non-virtualizing ItemsControl for large lists <ListBox ItemsSource="{Binding LargeList}"/> <ItemsControl><StackPanel> for 10K items High https://docs.avaloniaui.net/docs/reference/controls/listbox
24 23 Performance Avoid unnecessary bindings Each binding has overhead Bind only properties that change Binding static labels and headers <TextBlock Text="{Binding DynamicTitle}"/> but static: <TextBlock Text="Settings"/> <TextBlock Text="{Binding SettingsLabel}"/> for constant string Low https://docs.avaloniaui.net/docs/data-binding/introduction-to-data-binding
25 24 Performance Set bitmap interpolation mode on scaled images RenderOptions.BitmapInterpolationMode controls image scaling quality vs cost; default may look aliased on upscaled or downscaled bitmaps RenderOptions.SetBitmapInterpolationMode tuned to the use case Default interpolation on scaled images that look blurry or aliased RenderOptions.SetBitmapInterpolationMode(image, BitmapInterpolationMode.HighQuality); Image scaled with Stretch and no interpolation hint set Low https://docs.avaloniaui.net/docs/concepts/image-interpolation
26 25 Performance Profile with Avalonia DevTools Built-in diagnostic tools DevTools for visual tree and binding inspection Console.WriteLine debugging Attach DevTools in debug mode with F12 Print statements to debug layout issues Medium https://docs.avaloniaui.net/docs/guides/implementation-guides/developer-tools
27 26 Architecture Use MVVM with ReactiveUI or CommunityToolkit Proven MVVM frameworks for Avalonia ReactiveUI or CommunityToolkit.Mvvm for ViewModels Code-behind for all logic public class MainViewModel : ReactiveObject { } MainWindow.axaml.cs with all business logic High https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/
28 27 Architecture Use ViewLocator pattern Convention-based View-ViewModel resolution ViewLocator for automatic view resolution Manual view instantiation and DataContext wiring class ViewLocator : IDataTemplate { Build(object data) => new MainView(); } new MainView { DataContext = new MainViewModel() } everywhere Medium https://docs.avaloniaui.net/docs/data-templates/view-locator
29 28 Architecture Use dependency injection Register services in a Microsoft.Extensions.DependencyInjection container during startup before any view is constructed - resolve ViewModels through the provider not via a static ServiceLocator Build the ServiceProvider in BuildAvaloniaApp or OnFrameworkInitializationCompleted then resolve ViewModels from it Static ServiceLocator or new-ing ViewModels inline in code-behind services.AddSingleton<IDataService, DataService>(); services.AddTransient<MainViewModel>(); var provider = services.BuildServiceProvider(); // wired before windows are created ServiceLocator.Current.GetInstance<IDataService>() called from random ViewModels with no registration ordering Medium https://docs.avaloniaui.net/docs/app-development/dependency-injection
30 29 Architecture Separate Views from ViewModels Keep UI and logic in separate projects ViewModels in a separate class library ViewModels in the same project referencing Avalonia types MyApp.Core (no Avalonia refs) + MyApp.Desktop (Avalonia views) ViewModel importing Avalonia.Controls Medium https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/
31 30 Accessibility Set AutomationProperties Enable screen reader support AutomationProperties.Name on interactive controls Controls without accessible names <Button AutomationProperties.Name="Close dialog"><PathIcon Data="..."/></Button> <Button><PathIcon/></Button> without accessible name High https://docs.avaloniaui.net/api/avalonia/automation/automationproperties
32 31 Accessibility Support keyboard navigation Full keyboard operability TabIndex and KeyboardNavigation properties Mouse-only interactions <Button TabIndex="1" Content="Save"/> Clickable controls without keyboard support High https://docs.avaloniaui.net/docs/input-interaction/keyboard-and-hotkeys
33 32 Accessibility Use semantic control types Controls convey meaning to assistive tech Button for actions ListBox for selection TextBlock with PointerPressed as fake button <Button Content="Submit"/> <TextBlock PointerPressed="OnSubmitClick" Text="Submit"/> High https://docs.avaloniaui.net/docs/reference/controls/
34 33 Testing Use Avalonia.Headless for UI tests Run UI tests without display server Avalonia.Headless for CI-compatible UI testing Skipping UI tests in CI [AvaloniaTest] public void Button_Click_Updates_Label() { ... } UI tests that require a display server Medium https://docs.avaloniaui.net/docs/concepts/headless/
35 34 Testing Unit test ViewModels Test business logic independently xUnit or NUnit on ViewModel methods Testing through UI only [Fact] public void AddItem_IncreasesCount() { vm.AddItem(); Assert.Equal(1, vm.Items.Count); } Manual testing by running the app Medium https://docs.avaloniaui.net/docs/concepts/headless/
36 35 Testing Test converters independently Value converters contain testable logic Unit tests on Convert and ConvertBack Assuming converters work without tests [Fact] public void BoolToColor_True_ReturnsGreen() { Assert.Equal(Brushes.Green, converter.Convert(true)); } No converter tests Low https://docs.avaloniaui.net/docs/data-binding/how-to-create-a-custom-data-binding-converter
37 36 Navigation Use ReactiveUI routing for navigation IScreen and RoutingState for page navigation ReactiveUI RoutingState with IScreen on main ViewModel Manual content swapping in code-behind public RoutingState Router { get; } = new(); Router.Navigate.Execute(new DetailViewModel()); contentControl.Content = new DetailView(); in code-behind Medium https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/routing
38 37 Navigation Use UserControl for views Pages and screens should be UserControls hosted in a ContentControl UserControl for each view with RoutedViewHost or ContentControl Window per page or nested Windows <UserControl x:Class="MyApp.Views.DetailView"> new Window() for each page in the app Medium https://docs.avaloniaui.net/docs/custom-controls/
39 38 Navigation Use page transitions for view switching Built-in transitions for smooth navigation CrossFade PageSlide or CompositePageTransition declared as a property element Abrupt 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 views Low https://docs.avaloniaui.net/docs/reference/controls/transitioningcontentcontrol
40 39 Navigation Support back navigation Maintain navigation history for complex apps Router.NavigateBack or custom back stack No way to return to previous views <Button Command="{Binding Router.NavigateBack}" Content="Back"/> Single-direction navigation with no back support Medium https://v11.docs.avaloniaui.net/docs/concepts/reactiveui/routing
41 40 Controls Use AutoCompleteBox for search Built-in autocomplete and suggestion control AutoCompleteBox with FilterMode and ItemsSource TextBox with manual Popup and ListBox for suggestions <AutoCompleteBox ItemsSource="{Binding Suggestions}" FilterMode="Contains"/> TextBox with custom Popup for autocomplete Medium https://docs.avaloniaui.net/docs/reference/controls/autocompletebox
42 41 Controls Use TabControl for tabbed interfaces Standard tabbed navigation and content switching TabControl with TabItem for tabbed layouts Manual toggle buttons swapping content <TabControl><TabItem Header="General"><GeneralView/></TabItem><TabItem Header="Advanced"><AdvancedView/></TabItem></TabControl> ToggleButtons with manual content switching logic Medium https://docs.avaloniaui.net/docs/reference/controls/tabcontrol
43 42 Controls Use SplitView for master-detail Collapsible pane layout for navigation or panels SplitView with Pane and Content areas Manual 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 sidebar Medium https://docs.avaloniaui.net/docs/reference/controls/splitview
44 43 Controls Use Flyout for contextual actions Attach popup menus and actions to controls Flyout and MenuFlyout on Button or other controls Custom 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 positioning Medium https://docs.avaloniaui.net/docs/reference/controls/flyouts
45 44 Lifecycle Use AppBuilder for app configuration Configure platform features and services at startup AppBuilder with UsePlatformDetect and fluent API Manual platform initialization AppBuilder.Configure<App>().UsePlatformDetect().WithInterFont().StartWithClassicDesktopLifetime(args); Manual platform-specific startup code per OS High https://docs.avaloniaui.net/docs/fundamentals/application-lifetimes
46 45 Lifecycle Initialize MainWindow in OnFrameworkInitializationCompleted Override 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 ready Override OnFrameworkInitializationCompleted and pattern-match on IClassicDesktopStyleApplicationLifetime for desktop-only setup Creating windows in the App constructor or assuming the same lifetime type on every platform public 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 type High https://docs.avaloniaui.net/docs/fundamentals/application-lifetimes
47 46 Animation Use CSS-like keyframe animations Avalonia supports declarative animations in XAML and code Animation with KeyFrame and Setter for property animations Manual timer-based property updates <Border.Transitions><DoubleTransition Property="Opacity" Duration="0:0:0.3"/></Border.Transitions> DispatcherTimer ticking to update Opacity manually Medium https://docs.avaloniaui.net/docs/graphics-animation/animations
48 47 Animation Use Transitions for implicit animations Automatic animation when property values change Transitions collection on controls for smooth changes Instant property changes with no visual feedback <Button.Transitions><TransformOperationsTransition Property="RenderTransform" Duration="0:0:0.2"/></Button.Transitions> Direct property set with no transition Low https://docs.avaloniaui.net/docs/graphics-animation/control-transitions
49 48 Performance Use compiled bindings and TrimmerRoots.xml for PublishAot Avalonia 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 them x:CompileBindings=True on every view plus TrimmerRoots.xml for runtime-resolved types PublishAot 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 configuration Medium https://docs.avaloniaui.net/docs/deployment/native-aot
50 49 Threading Marshal cross-thread work to the UI thread Avalonia controls and bound properties are not thread-safe and touching them off the UI thread throws InvalidOperationException Dispatcher.UIThread.Post or InvokeAsync to bounce work back to the UI thread Direct property writes from Task.Run or background threads await Dispatcher.UIThread.InvokeAsync(() => Status = "Done"); Task.Run(() => { Status = "Done"; }); // throws Call from invalid thread High https://docs.avaloniaui.net/docs/app-development/threading
51 50 Commands Use AsyncRelayCommand or ReactiveCommand for async work Async-aware commands disable themselves while running and surface CancellationToken so users cannot double-invoke a long operation [RelayCommand] async Task method or ReactiveCommand.CreateFromTask async 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(); } High https://docs.avaloniaui.net/docs/input-interaction/commanding
52 51 Styling Use DynamicResource for theme-aware brushes ResourceDictionary.ThemeDictionaries entries must be looked up via DynamicResource - StaticResource resolves once at load and won't update when the active theme variant changes DynamicResource for brushes and colors that follow the active theme variant Hardcoded 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 variants Medium https://docs.avaloniaui.net/docs/app-development/resource-dictionary
53 52 Input Use HotKey or KeyBinding for keyboard shortcuts Built-in HotKey on ICommandSource and Window.KeyBindings handle modifier keys focus scoping and cross-platform Ctrl/Cmd mapping HotKey on a command-bound control or KeyBinding on the Window Manual KeyDown handlers checking Key and KeyModifiers <Button Command="{Binding SaveCommand}" HotKey="Ctrl+S" Content="Save"/> OnKeyDown checking e.Key == Key.S && e.KeyModifiers == KeyModifiers.Control Medium https://docs.avaloniaui.net/docs/input-interaction/mouse-and-keyboard-shortcuts
54 53 Windowing Customize window chrome with ExtendClientAreaToDecorationsHint Set ExtendClientAreaToDecorationsHint to extend content into the title bar area and tag a region with WindowDecorationProperties.ElementRole=TitleBar to keep native drag and maximize behavior ExtendClientAreaToDecorationsHint plus a region tagged ElementRole=TitleBar SystemDecorations=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-behind Medium https://docs.avaloniaui.net/docs/app-development/window-management
55 54 Storage Use TopLevel.StorageProvider for file pickers The legacy OpenFileDialog/SaveFileDialog APIs are obsolete in Avalonia 11 - use TopLevel.GetTopLevel(this).StorageProvider with OpenFilePickerAsync/SaveFilePickerAsync/OpenFolderPickerAsync which returns IStorageFile/IStorageFolder and works on desktop mobile and browser TopLevel.StorageProvider with OpenFilePickerAsync and FilePickerOpenOptions OpenFileDialog or SaveFileDialog from older Avalonia samples or copied from WPF var 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 API High https://docs.avaloniaui.net/docs/concepts/services/storage-provider/
56 55 Windowing Use TrayIcon for system tray icon TrayIcon 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 desktops TrayIcon with NativeMenu inside TrayIcon.Icons on the Application Custom 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/Invoke Medium https://docs.avaloniaui.net/docs/controls/tray-icon
57 56 Cross-Platform Use OnPlatform and OnFormFactor markup for per-OS values OnPlatform 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 sizes OnPlatform with Default Windows macOS Linux entries directly in the property setter RuntimeInformation.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()) ... Medium https://docs.avaloniaui.net/docs/platform-specific-guides/xaml

View File

@@ -0,0 +1,60 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,XAML,Use WinUI XAML API surface,Uno implements the WinUI API across platforms,Microsoft.UI.Xaml namespace for all UI code,WPF or Xamarin.Forms namespaces,"using Microsoft.UI.Xaml.Controls;","using System.Windows.Controls; or using Xamarin.Forms;",High,https://platform.uno/docs/articles/implemented-views.html
2,XAML,Check API implementation status,Not all WinUI APIs are implemented on every platform,Uno API compatibility docs before using new APIs,Assuming all WinUI APIs work everywhere,"Check platform.uno/docs for API status","Using unimplemented API and discovering at runtime",High,https://platform.uno/docs/articles/implemented-views.html
3,XAML,Use Uno.WinUI not Uno.UI for new projects,Uno.WinUI uses WinUI 3 APIs,Uno.WinUI NuGet packages for new projects,Uno.UI (UWP API surface) for new projects,"<Project Sdk=""Uno.Sdk""> (Uno.WinUI / WinUI 3 surface implicit)","<PackageReference Include=""Uno.UI""/> (legacy UWP API surface)",Medium,https://platform.uno/docs/articles/updating-to-winui3.html
4,XAML,Use XAML Hot Reload,Speed up development with live XAML editing,Hot Reload for iterating on layouts,Restarting app for every XAML change,"Click Hot Reload button in VS toolbar or save in VS Code/Rider to apply XAML changes","Full rebuild for margin tweak",Medium,https://platform.uno/docs/articles/features/working-with-xaml-hot-reload.html
5,Conditional,Use platform-specific XAML,Conditional namespaces for platform-specific UI,xmlns:android xmlns:ios xmlns:wasm for platform XAML,Shared XAML when platforms need different controls,"<TextBlock android:Text=""Android"" ios:Text=""iOS"" Text=""Default""/>","#if in code-behind to set text per platform",Medium,https://platform.uno/docs/articles/platform-specific-xaml.html
6,Conditional,Use partial classes for platform code,Separate platform implementations in partial files,Partial class files with platform-specific logic,#if directives in shared code for large blocks,"MainPage.iOS.cs MainPage.Android.cs partial class files","#if __IOS__ ... #elif __ANDROID__ ... 100-line blocks in shared file",Medium,https://platform.uno/docs/articles/platform-specific-csharp.html
7,Conditional,Use preprocessor symbols correctly,Target correct platforms with defines,__IOS__ __ANDROID__ __WASM__ __DESKTOP__ for platform checks,Inventing custom symbols or checking OS at runtime,"#if __ANDROID__ Android-specific code #endif","if (RuntimeInformation.IsOSPlatform(OSPlatform.Android)) for compile-time choice",Medium,https://platform.uno/docs/articles/platform-specific-csharp.html
8,Conditional,Minimize platform-specific code,Keep shared code maximized,Abstract platform differences behind interfaces,Duplicating logic across platform files,"IDeviceService with per-platform implementation","Same 50 lines copy-pasted into iOS and Android partial classes",High,https://platform.uno/docs/articles/platform-specific-csharp.html
9,Navigation,Use Frame-based navigation,Standard WinUI navigation pattern,Frame.Navigate with page types,Manual content swapping,"rootFrame.Navigate(typeof(DetailPage), parameter);","contentPresenter.Content = new DetailPage();",Medium,https://platform.uno/docs/articles/guides/native-frame-nav-tutorial.html
10,Navigation,Use Uno.Extensions.Navigation,Type-safe navigation with DI integration,Uno.Extensions navigation for complex apps,Manual Frame management in large apps,"navigator.NavigateViewModelAsync<DetailViewModel>(this, data: item);","Frame.Navigate with string parsing everywhere",Medium,https://platform.uno/docs/articles/external/uno.extensions/doc/Overview/Navigation/NavigationOverview.html
11,Navigation,Handle platform back navigation,SystemNavigationManager.BackRequested works on Android iOS and WASM but is unimplemented on WinAppSDK desktop where calling GetForCurrentView() throws at runtime,Subscribe to BackRequested only on platforms that support it or use Uno.Toolkit NavigationBar for cross-platform back UX,Calling SystemNavigationManager.GetForCurrentView() on WinUI 3 desktop without a guard,"#if __ANDROID__ || __IOS__ || __WASM__ SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested; #endif","SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested; with no platform guard — crashes on Windows desktop",High,https://platform.uno/docs/articles/guides/native-frame-nav-tutorial.html
12,Navigation,Use deep linking,Support URI activation across platforms,Handle protocol activation and URI routing,Single entry point ignoring activation,Route URIs to specific pages on activation,Ignoring OnLaunched activation args,Medium,https://platform.uno/docs/articles/features/protocol-activation.html
13,Renderers,Understand Skia vs native rendering,Uno offers both rendering approaches,Skia for pixel-perfect cross-platform consistency,Assuming native rendering on all platforms,"<TargetFrameworks>net10.0-desktop;net10.0-browserwasm</TargetFrameworks> uses unified Skia Desktop shell","Expecting platform-native controls on Skia targets",High,https://platform.uno/docs/articles/features/using-skia-desktop.html
14,Renderers,Use unified net10.0-desktop target,Uno 5.2+ ships a single Skia Desktop shell that auto-selects X11 Win32 or AppKit per OS — Skia.Gtk Skia.Linux.Framebuffer and Skia.WPF heads are deprecated,net10.0-desktop TFM with UnoPlatformHostBuilder for cross-platform desktop,Targeting the legacy Skia.Gtk or Skia.Linux.Framebuffer heads in new projects,"<TargetFrameworks>net10.0-desktop</TargetFrameworks> in the Uno.Sdk single project","Per-OS Skia.Gtk Skia.MacOS Skia.Linux.Framebuffer head projects",Medium,https://platform.uno/docs/articles/features/using-skia-desktop.html
15,Renderers,Test rendering on each target,Visual differences exist between renderers,Visual testing on each active target platform,Testing only on Windows assuming others match,"Screenshot tests on iOS Android WASM and Desktop","Testing only on Windows Desktop",High,https://platform.uno/docs/articles/external/uno.uitest/doc/using-uno-uitest.html
16,Renderers,Use platform-native features when needed,Access native APIs through Uno abstractions,Native platform APIs via platform-specific code,Avoiding native features for purity,"#if __IOS__ UIKit API call #endif for camera access","Pure shared code that avoids using the camera",Medium,https://platform.uno/docs/articles/platform-specific-csharp.html
17,Performance,Optimize WASM bundle size,WebAssembly downloads can be large,IL linker and AOT for smaller WASM bundles,Default settings for production WASM,"<WasmShellILLinkerEnabled>true</WasmShellILLinkerEnabled>","Publishing WASM without linker",High,https://platform.uno/docs/articles/features/using-il-linker-webassembly.html
18,Performance,Use x:Load for deferred XAML,Defer element creation until needed,x:Load=False for hidden panels and tabs,Loading all UI elements upfront,"<StackPanel x:Load=""{x:Bind ShowAdvanced}"">","Always-loaded Collapsed panels",Medium,https://platform.uno/docs/articles/features/windows-ui-xaml-xbind.html
19,Data Binding,Use x:Bind for compiled bindings,Compiled bindings eliminate runtime reflection — Uno supports x:Bind across iOS Android WASM Skia and Windows targets that compile XAML so prefer it over {Binding} for static well-typed bindings,x:Bind for property and event bindings; reserve {Binding} for runtime-typed DataContext scenarios,{Binding} everywhere when x:Bind would compile,"<TextBlock Text=""{x:Bind ViewModel.Title, Mode=OneWay}""/>","<TextBlock Text=""{Binding Title}""/> for a statically known property",High,https://platform.uno/docs/articles/features/windows-ui-xaml-xbind.html
20,Performance,Profile per platform,Performance characteristics vary by target,Platform-specific profiling tools,Assuming desktop perf equals mobile,"Instruments on iOS and Android Profiler on Android","Profiling only on Windows",Medium,https://platform.uno/docs/articles/guides/profiling-applications.html
21,Styling,Use WinUI theme resources,Consistent theming across platforms,ThemeResource for adaptive colors,Hardcoded colors per platform,"Background=""{ThemeResource ApplicationPageBackgroundThemeBrush}""","Background=""#FFFFFF""",High,https://platform.uno/docs/articles/features/working-with-themes.html
22,Styling,Support light and dark themes,Application.RequestedTheme accepts only ApplicationTheme.Light/Dark — to follow the system theme leave it unset entirely. ElementTheme.Default exists only on FrameworkElement.RequestedTheme not on Application,Omit Application.RequestedTheme so the OS theme wins; use RequestedTheme=Default on FrameworkElement to inherit from parent,Setting Application.RequestedTheme=""Default"" — not a valid ApplicationTheme value and throws at parse time,"<Application></Application> with RequestedTheme unset; <Grid RequestedTheme=""Default"">...</Grid> on a FrameworkElement","<Application RequestedTheme=""Default""> // not a valid ApplicationTheme",Medium,https://platform.uno/docs/articles/features/working-with-themes.html
23,Styling,Use Lightweight Styling,Override control sub-properties via resources,Lightweight styling keys for minor tweaks,Full ControlTemplate for small changes,"<Button><Button.Resources><StaticResource x:Key=""ButtonBackground"" ResourceKey=""AccentBrush""/></Button.Resources></Button>","Copying entire ControlTemplate to change one color",Medium,https://platform.uno/docs/articles/external/uno.themes/doc/lightweight-styling.html
24,Styling,Test themes on each platform,Theme rendering differs across platforms,Visual theme testing on all targets,Assuming themes look identical everywhere,"Screenshot comparison across platforms for themed controls","Theming only tested on Windows",Low,https://platform.uno/docs/articles/features/working-with-themes.html
25,Architecture,Use MVVM pattern,Separate view and logic,CommunityToolkit.Mvvm or Prism for MVVM,Code-behind for business logic,"[ObservableProperty] public partial string Title { get; set; } [RelayCommand] private void Save() { }","MainPage.xaml.cs with all logic",High,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
26,Architecture,Use Uno.Extensions,Official extension libraries for common patterns,Uno.Extensions for DI navigation configuration,Building infrastructure from scratch,"Host.CreateDefaultBuilder().UseNavigation().UseConfiguration()","Manual DI and navigation setup",Medium,https://platform.uno/docs/articles/external/uno.extensions/doc/ExtensionsOverview.html
27,Architecture,Use dependency injection,Register services for testability,Microsoft.Extensions.DI through Uno.Extensions,Static service locators and singletons,"services.AddSingleton<IApiService, ApiService>();","ApiService.Instance or new ApiService() in ViewModels",Medium,https://platform.uno/docs/articles/external/uno.extensions/doc/Learn/DependencyInjection/DependencyInjectionOverview.html
28,Architecture,Share code via class libraries,Maximize code reuse across targets,Business logic in .NET Standard or shared library,Business logic in platform head projects,"MyApp.Core class library referenced by all heads","Business logic in MyApp.Wasm.csproj",Medium,https://platform.uno/docs/articles/cross-targeted-libraries.html
29,Architecture,Use Uno.Resizetizer for assets,Single source SVG to multi-platform assets,UnoImage for automatic asset generation from SVG,Manual asset export per resolution and platform,"<UnoImage Include=""Assets/icon.svg"" BaseSize=""24,24""/>","Manually exporting icon_1x.png icon_2x.png icon_3x.png per platform",Medium,https://platform.uno/docs/articles/external/uno.resizetizer/doc/using-uno-resizetizer.html
30,Accessibility,Set AutomationProperties,Enable screen readers across platforms,AutomationProperties.Name on interactive controls,Controls without accessible names,"<Button AutomationProperties.Name=""Submit form""><SymbolIcon Symbol=""Accept""/></Button>","<Button><SymbolIcon Symbol=""Accept""/></Button> without name",High,https://platform.uno/docs/articles/features/working-with-accessibility.html
31,Accessibility,Test accessibility per platform,Each platform has different assistive tech,Test with VoiceOver TalkBack and Narrator,Testing accessibility on one platform only,"VoiceOver on iOS + TalkBack on Android + Narrator on Windows","Only testing with Narrator on Windows",High,https://platform.uno/docs/articles/features/working-with-accessibility.html
32,Accessibility,Support platform text scaling,Respect user font size preferences,Dynamic font scaling for all text,Fixed font sizes ignoring accessibility,"FontSize=""{ThemeResource BodyTextBlockFontSize}""","FontSize=""14"" everywhere",Medium,https://platform.uno/docs/articles/features/working-with-accessibility.html
33,Testing,Unit test ViewModels,Test business logic independently,xUnit or MSTest on shared ViewModel code,UI testing only,"[Fact] public void LoadData_SetsItems() { vm.Load(); Assert.NotEmpty(vm.Items); }","Manual testing on each platform",Medium,https://platform.uno/docs/articles/external/uno.uitest/doc/using-uno-uitest.html
34,Testing,Use Uno.UITest for integration,Cross-platform UI testing framework,Uno.UITest for automated UI tests across platforms,Manual regression testing,"app.WaitForElement(""SaveButton""); app.Tap(""SaveButton"");","Manual click-through on each platform",Medium,https://platform.uno/docs/articles/external/uno.uitest/doc/using-uno-uitest.html
35,WASM,Show an extended splash screen on WASM,WASM bundle download and runtime startup take several seconds on first load — render branded UI immediately so users do not see a blank page (AOT and trimming are covered separately),Render a splash overlay in wwwroot/index.html that hides on first XAML navigation,Letting the user wait on a blank white page while the runtime boots,"index.html: <div id=""uno-loading"">Loading…</div> hidden via JS interop after first Frame.Navigate","No splash markup in index.html — 5-second blank page on first visit",Medium,https://platform.uno/docs/articles/external/uno.wasm.bootstrap/doc/runtime-execution-modes.html
36,WASM,Use AOT compilation for performance,Ahead-of-time compilation improves runtime speed,AOT for production WASM builds,Interpreter mode in production,"<WasmShellMonoRuntimeExecutionMode>InterpreterAndAOT</WasmShellMonoRuntimeExecutionMode>","Default interpreter mode in production deployment",Medium,https://platform.uno/docs/articles/external/uno.wasm.bootstrap/doc/runtime-execution-modes.html
37,WASM,Handle browser limitations,WASM runs in browser sandbox,Feature detection for browser APIs,Assuming desktop capabilities in browser,"[JSImport(""globalThis.hasApi"")] static partial bool HasApi(); #if __WASM__ if (HasApi()) { ... } #endif","#if __WASM__ StorageFile.GetFileFromPathAsync(""C:/data"") #endif",Medium,https://platform.uno/docs/articles/platform-specific-csharp.html
38,Controls,Use NavigationView for app shell,WinUI NavigationView for consistent navigation across platforms,NavigationView with MenuItems for app navigation,Custom hamburger menu implementation,"<NavigationView><NavigationView.MenuItems><NavigationViewItem Content=""Home"" Icon=""Home""/></NavigationView.MenuItems></NavigationView>","Custom SplitView with manual toggle button",High,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/navigationview
39,Controls,Use ContentDialog for modal interactions,Cross-platform modal dialogs using WinUI API,ContentDialog for confirmations and input,Custom overlay Panel as dialog,"<ContentDialog Title=""Confirm"" PrimaryButtonText=""OK"" CloseButtonText=""Cancel""/>","Grid overlay with manual focus trapping",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/dialogs-and-flyouts/dialogs
40,Controls,Use CommandBar for app actions,Standard command bar with primary and secondary commands,CommandBar with AppBarButtons for toolbar actions,Custom StackPanel toolbar,"<CommandBar><AppBarButton Icon=""Save"" Label=""Save""/><AppBarButton Icon=""Delete"" Label=""Delete""/></CommandBar>","<StackPanel Orientation=""Horizontal""><Button>Save</Button></StackPanel>",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/command-bar
41,Controls,Use ToggleSwitch for boolean settings,Platform-native toggle control for on/off preferences,ToggleSwitch for settings and feature flags,CheckBox for toggle settings,"<ToggleSwitch Header=""Dark Mode"" IsOn=""{x:Bind ViewModel.IsDarkMode, Mode=TwoWay}""/>","<CheckBox Content=""Enable dark mode""/>",Low,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/toggles
42,Data Binding,Implement INotifyPropertyChanged,Enable UI updates when ViewModel properties change,CommunityToolkit.Mvvm [ObservableProperty] for auto-notification,Properties without change notification,"[ObservableProperty] public partial string Title { get; set; }","public string Title { get; set; } without notification",High,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
43,Data Binding,Use ObservableCollection for bound lists,Collection change notifications for ItemsSources across platforms,ObservableCollection<T> for data-bound lists,List<T> for bound ItemsSources,"ObservableCollection<Item> Items { get; } = new();","List<Item> Items { get; set; } = new();",High,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
44,Lifecycle,Handle app suspension on mobile,iOS and Android may suspend or terminate the app — WinAppSDK desktop does not raise Suspending so use window Closed for desktop save-state,Save state in OnSuspending and restore on activation,Ignoring lifecycle losing user state on mobile,"Application.Current.Suspending += (s, e) => { var d = e.SuspendingOperation.GetDeferral(); SaveState(); d.Complete(); };","No suspend handler losing form data on mobile",High,https://platform.uno/docs/articles/features/windows-ui-xaml-application.html
45,Lifecycle,Use Uno.Extensions.Hosting for startup,Structured app initialization with DI and configuration,IHost builder pattern for app startup and service registration,Manual initialization in App constructor,"Host.CreateDefaultBuilder().ConfigureServices(s => s.AddSingleton<MainViewModel>()).Build();","new MainViewModel() in App.xaml.cs constructor",Medium,https://platform.uno/docs/articles/external/uno.extensions/doc/Overview/Hosting/HostingOverview.html
46,Performance,Use ListView virtualization for large lists,Only renders visible items to reduce memory and layout cost,ListView with default ItemsStackPanel virtualization,ItemsControl or StackPanel for large data sets,"<ListView ItemsSource=""{x:Bind Items}""/> (virtualizes by default)","<ItemsControl><StackPanel> rendering 5000 items at once",High,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/listview-and-gridview
47,Accessibility,Support keyboard navigation on desktop,Skia and WinAppSDK targets need full keyboard operability — note TabIndex routing is not fully implemented on every Uno target,AccessKey and KeyboardAccelerator on Skia and WinAppSDK targets,Mouse-only interactions on desktop,"<Button AccessKey=""S"" Content=""Save""><Button.KeyboardAccelerators><KeyboardAccelerator Modifiers=""Control"" Key=""S""/></Button.KeyboardAccelerators></Button>","Clickable controls without keyboard support on desktop",High,https://learn.microsoft.com/en-us/windows/apps/develop/input/keyboard-accelerators
48,WASM,Use service workers for offline support,Enable PWA capabilities for WASM deployments,Service worker registration for caching and offline mode,Online-only WASM app with no offline fallback,"<WasmPWAManifestFile>manifest.webmanifest</WasmPWAManifestFile>","No service worker leaving WASM app unusable offline",Low,https://platform.uno/docs/articles/external/uno.wasm.bootstrap/doc/features-pwa.html
49,Performance,Marshal to UI thread with DispatcherQueue,Cross-thread access to UI elements throws — capture the UI DispatcherQueue once and use TryEnqueue to update from background work,DispatcherQueue.GetForCurrentThread().TryEnqueue from background work,Touching UI controls directly from a Task,"_dispatcher.TryEnqueue(() => StatusText.Text = ""Done"");","await Task.Run(() => StatusText.Text = ""Done""); throws on non-UI thread",High,https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.dispatching.dispatcherqueue
50,Styling,Merge XamlControlsResources in App.xaml,Required for Fluent control styles to load — without it controls render with no template,Add XamlControlsResources at the top of Application.Resources MergedDictionaries,Skipping the merged dictionary and wondering why Buttons look unstyled,"<Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><XamlControlsResources xmlns=""using:Microsoft.UI.Xaml.Controls""/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources>","<Application.Resources><SolidColorBrush x:Key=""MyBrush"" Color=""Red""/></Application.Resources> with no XamlControlsResources merged",High,https://platform.uno/docs/articles/features/fluent-styles.html
51,Architecture,Use async [RelayCommand] for I/O,AsyncRelayCommand reports CanExecute=false (raising CanExecuteChanged) and exposes IsRunning while the Task is in flight — the bound control is disabled and re-entrancy is prevented by default (AllowConcurrentExecutions=false),[RelayCommand] on a Task-returning method for awaitable work,async void event handlers calling .Wait() or .Result,"[RelayCommand] private async Task LoadAsync() { Items = await _api.GetAsync(); }","public void OnLoadClick(object s, EventArgs e) { LoadAsync().Wait(); } deadlock risk",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/generators/relaycommand
52,Architecture,Use x:Uid for localized strings,WinUI x:Uid resolves UI text from .resw resources at runtime — use it instead of hardcoded strings to support localization across iOS Android WASM and desktop from a single project,x:Uid on every user-facing string with matching .resw entries per language under Strings/{lang}/Resources.resw,Hardcoding language-specific strings into XAML or code-behind,"<Button x:Uid=""SubmitButton""/> with Strings/en/Resources.resw entry SubmitButton.Content=Submit","<Button Content=""Submit""/> hardcoded in XAML",High,https://platform.uno/docs/articles/features/working-with-strings.html
53,Architecture,Wire up ILogger via Uno.Extensions.Logging,Cross-platform logging routes to platform-native sinks (OSLog on iOS Console on WASM Debug elsewhere) when configured through the IHost builder,Inject ILogger<T> into ViewModels and services and call UseLogging() on the host builder,Console.WriteLine or platform-specific log APIs scattered across shared code,"Host.CreateDefaultBuilder().UseLogging(c => c.SetMinimumLevel(LogLevel.Information)) and ILogger<MainViewModel> via constructor injection","Console.WriteLine(""error"") in shared code with no platform-aware routing",Medium,https://platform.uno/docs/articles/external/uno.extensions/doc/Overview/Logging/LoggingOverview.html
54,Performance,Enable PublishAot on net10.0-desktop,Skia Desktop on .NET 10 supports Native AOT for faster cold start and smaller deployments — opt in per-target so debug builds remain fast,<PublishAot>true</PublishAot> in a TFM-conditional PropertyGroup for net10.0-desktop release builds,Enabling PublishAot globally and breaking debug iteration on every TFM,"<PropertyGroup Condition=""'$(TargetFramework)'=='net10.0-desktop' AND '$(Configuration)'=='Release'""><PublishAot>true</PublishAot></PropertyGroup>","<PublishAot>true</PublishAot> at root with no TFM/Configuration condition",Medium,https://platform.uno/docs/articles/features/using-skia-desktop.html
55,Performance,Never block on async with .Result or .Wait(),Blocking on a Task from the UI thread deadlocks because the awaiter cannot resume on the captured SynchronizationContext — always await async APIs through to the event handler,Await async methods all the way up; in libraries call ConfigureAwait(false) to avoid context capture,Calling .Result .Wait() or GetAwaiter().GetResult() on a Task from the UI thread,"private async void OnLoadClick(object s, RoutedEventArgs e) { var data = await _api.GetAsync(); Items = data; }","private void OnLoadClick(object s, RoutedEventArgs e) { var data = _api.GetAsync().Result; } // deadlocks on UI thread",High,https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/
56,Styling,Define ThemeDictionaries for Light Dark and HighContrast,Resources placed inside ResourceDictionary.ThemeDictionaries entries are automatically swapped when the system theme changes — required for theme-aware brushes,Wrap brushes in a ThemeDictionaries dictionary keyed by Light Dark and HighContrast in App.xaml or page resources,Defining a single brush at the root and missing dark/high-contrast variants,"<ResourceDictionary.ThemeDictionaries><ResourceDictionary x:Key=""Light""><SolidColorBrush x:Key=""Brand"" Color=""#005A9E""/></ResourceDictionary><ResourceDictionary x:Key=""Dark""><SolidColorBrush x:Key=""Brand"" Color=""#3A96DD""/></ResourceDictionary></ResourceDictionary.ThemeDictionaries>","<SolidColorBrush x:Key=""Brand"" Color=""#005A9E""/> at root with no theme variants",Medium,https://platform.uno/docs/articles/features/working-with-themes.html
57,Architecture,Use Uno.Sdk with UnoFeatures,Uno.Sdk is the modern single-project SDK that auto-resolves Uno.WinUI Uno.Toolkit Material and other packages from a UnoFeatures property — declare features by name instead of hand-managing dozens of PackageReferences,Declare features in the csproj via <UnoFeatures>...</UnoFeatures> and let the SDK resolve transitive packages,Hand-adding every Uno.* PackageReference and matching version numbers across packages,"<Project Sdk=""Uno.Sdk""><PropertyGroup><UnoFeatures>Material;Hosting;Toolkit;Logging;MVVM</UnoFeatures></PropertyGroup></Project>","<PackageReference Include=""Uno.WinUI""/><PackageReference Include=""Uno.Material.WinUI""/> ... duplicated per feature with mismatched versions",Medium,https://platform.uno/docs/articles/features/using-the-uno-sdk.html
58,Lifecycle,Persist desktop window state via Window.Closed,WinAppSDK and Skia desktop heads do not raise Application.Suspending — handle the Window.Closed event (and AppWindow size/position changes) to save user state when desktop apps shut down,Subscribe to MainWindow.Closed and persist any unsaved state before the window is destroyed,Relying on Application.Suspending to fire on desktop targets,"m_window.Closed += (s, e) => SaveState();","Application.Current.Suspending += SaveState; // never fires on WinAppSDK or Skia desktop",Medium,https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.window
59,Architecture,Use WinRT.Interop for native window handle on Windows,Calling Win32 APIs from a WinUI Window (file pickers icon embedding etc.) requires the HWND — retrieve it via WinRT.Interop.WindowNative.GetWindowHandle and guard the call so non-Windows targets stay unaffected,GetWindowHandle inside a #if WINDOWS block when you need the HWND,Calling WinRT.Interop in shared code without a platform guard,"#if WINDOWS\nvar hWnd = WinRT.Interop.WindowNative.GetWindowHandle(MainWindow);\n#endif","var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(MainWindow); // breaks build on iOS Android WASM",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/retrieve-hwnd
Can't render this file because it contains an unexpected character in line 23 and column 412.

View File

@@ -0,0 +1,56 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,XAML,Use x:Bind for compiled bindings,Compile-time validated bindings with better performance,x:Bind for type-safe performant bindings,{Binding} when x:Bind is available,"<TextBlock Text=""{x:Bind ViewModel.Name, Mode=OneWay}""/>","<TextBlock Text=""{Binding Name}""/>",High,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
2,XAML,Use x:Load for deferred elements,Delay creation of elements until needed,x:Load=False for hidden or conditional panels,Loading all UI elements at page load,"<StackPanel x:Name=""AdvancedPanel"" x:Load=""{x:Bind ShowAdvanced, Mode=OneWay}"">","Collapsed StackPanel that is always instantiated",Medium,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-load-attribute
3,XAML,Use x:Phase for incremental item rendering,Render list items in priority phases,x:Phase on secondary content in item DataTemplates,All template content loaded in one pass,"<TextBlock x:Phase=""1"" Text=""{x:Bind Description}""/>","Complex DataTemplate with no phasing",Medium,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-phase-attribute
4,XAML,Use x:DefaultBindMode,Reduce repetitive Mode= declarations,x:DefaultBindMode=OneWay on containers,Mode=OneWay on every individual x:Bind,"<StackPanel x:DefaultBindMode=""OneWay"">","Mode=OneWay repeated on every binding in a panel",Low,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
5,XAML,Use x:DeferLoadStrategy for legacy support,Deferred loading before x:Load was available,x:Load (preferred) or x:DeferLoadStrategy=Lazy,Eagerly loading rarely shown UI,"x:Load=""False"" (or x:DeferLoadStrategy=""Lazy"" on older targets)","Always-loaded panels toggled with Visibility",Low,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-deferloadstrategy-attribute
6,Controls,Use NavigationView for app shell,Standard UWP navigation pattern with hamburger menu,NavigationView for top-level navigation,Custom SplitView hamburger menu,"<NavigationView><NavigationView.MenuItems><NavigationViewItem Content=""Home"" Icon=""Home""/></NavigationView.MenuItems></NavigationView>","Custom SplitView with manual toggle button",High,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/navigationview
7,Controls,Use CommandBar for app actions,Standard app bar for primary commands,CommandBar with AppBarButtons,Custom StackPanel toolbar,"<CommandBar><AppBarButton Icon=""Save"" Label=""Save""/></CommandBar>","<StackPanel Orientation=""Horizontal""><Button>Save</Button></StackPanel>",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/command-bar
8,Controls,Use ContentDialog for modals,System-styled modal dialogs,ContentDialog for confirmations and input,Custom popup overlays,"<ContentDialog Title=""Confirm"" PrimaryButtonText=""Yes"" CloseButtonText=""No""/>","Grid overlay with manual focus trapping",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/dialogs-and-flyouts/dialogs
9,Controls,Use AutoSuggestBox for search,Built-in search box with suggestions,AutoSuggestBox with QuerySubmitted and SuggestionChosen,TextBox with manual suggestion popup,"<AutoSuggestBox QueryIcon=""Find"" TextChanged=""OnTextChanged"" SuggestionChosen=""OnChosen"" QuerySubmitted=""OnQuerySubmitted""/>","TextBox with custom Popup and ListBox for suggestions",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/auto-suggest-box
10,Controls,Use CalendarDatePicker and TimePicker,Platform-consistent date and time selection,Built-in date and time pickers,Custom date selection controls,"<CalendarDatePicker Header=""Start date""/><TimePicker Header=""Time""/>","TextBox with date parsing and validation",Low,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/date-and-time
11,Controls,Use PersonPicture for user avatars,Consistent avatar display with fallback initials,PersonPicture with DisplayName and ProfilePicture,Custom Ellipse with ImageBrush for avatars,"<PersonPicture DisplayName=""Jane Doe"" ProfilePicture=""{x:Bind AvatarUri}""/>","<Ellipse><Ellipse.Fill><ImageBrush ImageSource=""avatar.png""/></Ellipse.Fill></Ellipse>",Low,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/person-picture
12,Styling,Use ThemeResource for adaptive colors,Colors that switch with light and dark theme,ThemeResource for all color references,Hardcoded hex values that break in dark mode,"Foreground=""{ThemeResource SystemControlForegroundBaseHighBrush}""","Foreground=""#000000""",High,https://learn.microsoft.com/en-us/windows/uwp/design/style/color
13,Styling,Use Fluent Design materials,Acrylic translucent material for depth,Built-in Fluent materials for depth and motion,Custom shader effects for blur and reveal,"<Grid Background=""{ThemeResource SystemControlAcrylicWindowBrush}""/>","Custom CompositionEffectBrush recreating acrylic",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/style/acrylic
14,Styling,Use Lightweight Styling,Override control resource keys for subtle changes,Lightweight styling resource overrides,Full ControlTemplate copy for small tweaks,"<Button><Button.Resources><SolidColorBrush x:Key=""ButtonBackground"" Color=""Blue""/></Button.Resources></Button>","Entire ControlTemplate copied to change background",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/xaml-styles#lightweight-styling
15,Styling,Use implicit styles for consistency,TargetType without x:Key applies to all instances,Implicit Style for default control appearance,Repeating Setters on every control instance,"<Style TargetType=""Button""><Setter Property=""CornerRadius"" Value=""4""/></Style>","CornerRadius=""4"" on every Button in the page",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/xaml-styles
16,Styling,Use VisualStateManager for visual states,Define visual states with Setters that change properties when triggered,VisualStateGroup containing VisualStates with Setter targets,Toggling Visibility from code-behind on SizeChanged,"<VisualStateGroup><VisualState x:Name=""Wide""><VisualState.Setters><Setter Target=""root.Orientation"" Value=""Horizontal""/></VisualState.Setters></VisualState></VisualStateGroup>","SizeChanged handler that flips Orientation in code-behind",High,https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml
17,Navigation,Use Frame for page navigation,Windows.UI.Xaml.Controls.Frame for UWP page navigation,Frame.Navigate with typed parameters,Swapping UserControls manually,"rootFrame.Navigate(typeof(DetailPage), itemId);","contentArea.Content = new DetailPage();",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/basics/navigate-between-two-pages
18,Navigation,Handle back button correctly,Provide an in-app Back button styled with NavigationBackButtonNormalStyle and handle SystemNavigationManager.BackRequested for hardware back gamepad B and Tablet-Mode back; also handle CoreDispatcher.AcceleratorKeyActivated for Alt+Left,In-app NavigationBackButtonNormalStyle button plus SystemNavigationManager.BackRequested handler,Relying on the deprecated title-bar back button (AppViewBackButtonVisibility) or ignoring system back signals,"SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;","No back button support on phone or tablet",High,https://learn.microsoft.com/en-us/windows/uwp/ui-input/back-navigation
19,Navigation,Support deep linking with protocol activation,Respond to URI activation and toast taps,OnActivated handler with proper page routing,Ignoring activation arguments,"protected override void OnActivated(IActivatedEventArgs args) { if (args.Kind == ActivationKind.Protocol) { ... } }","Empty OnActivated ignoring URI parameters",Medium,https://learn.microsoft.com/en-us/windows/uwp/launch-resume/handle-uri-activation
20,Navigation,Use ConnectedAnimations for continuity,Smooth transitions between pages,ConnectedAnimationService for shared element transitions,Abrupt page transitions with no visual continuity,"ConnectedAnimationService.GetForCurrentView().PrepareToAnimate(""image"", sourceImage);","No transition animation between list and detail",Low,https://learn.microsoft.com/en-us/windows/uwp/design/motion/connected-animation
21,Data Binding,Implement INotifyPropertyChanged,Enable UI updates on property changes,INotifyPropertyChanged on all ViewModels,Auto-properties without notification,"public string Title { get => _title; set { _title = value; OnPropertyChanged(); } }","public string Title { get; set; } expecting UI updates",High,https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
22,Data Binding,Use ObservableCollection for lists,Collection change notifications for ItemsSources,ObservableCollection<T> for bound lists,List<T> for data-bound collections,"ObservableCollection<Item> Items { get; } = new();","List<Item> Items { get; set; } = new();",High,https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
23,Data Binding,Use function bindings with x:Bind,Call static methods directly in markup,x:Bind to static converter methods,IValueConverter for trivial transforms,"<TextBlock Visibility=""{x:Bind local:Converters.BoolToVisibility(IsActive), Mode=OneWay}""/>","Full IValueConverter class for bool to Visibility",Medium,https://learn.microsoft.com/en-us/windows/uwp/data-binding/function-bindings
24,Data Binding,Specify Mode on x:Bind,x:Bind defaults to OneTime not OneWay,Mode=OneWay or TwoWay when live updates needed,Omitting Mode and getting stale UI,"Text=""{x:Bind Title, Mode=OneWay}""","Text=""{x:Bind Title}"" expecting live updates",High,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
25,Data Binding,Use CollectionViewSource for grouping,Group and sort collections declaratively,CollectionViewSource for grouped ListView and GridView,Manual grouping logic in code-behind,"<CollectionViewSource x:Key=""GroupedItems"" IsSourceGrouped=""True"" Source=""{x:Bind GroupedData}""/>","Manual loop building grouped StackPanels",Medium,https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
26,Performance,Use ListView and GridView virtualization,Only creates containers for visible items,Default virtualization in ListView and GridView,Setting ItemsPanel to non-virtualizing panel,"<ListView ItemsSource=""{x:Bind Items}""/> (virtualizes by default)","<ListView><ListView.ItemsPanel><ItemsPanelTemplate><StackPanel/></ItemsPanelTemplate></ListView.ItemsPanel></ListView>",High,https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-gridview-and-listview
27,Performance,Use ISupportIncrementalLoading,Load data on demand as user scrolls,ISupportIncrementalLoading for large datasets,Loading entire collection upfront,"class IncrementalSource : ObservableCollection<Item>, ISupportIncrementalLoading","await LoadAll() loading 50K items at startup",Medium,https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
28,Performance,Reduce XAML visual tree depth,Simpler trees layout and render faster,Flat templates with minimal nesting,Deeply nested panels in DataTemplates,"<StackPanel><TextBlock/><TextBlock/></StackPanel> in item template","<Grid><Border><StackPanel><Grid>... 8 levels in item template",Medium,https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-xaml-loading
29,Performance,Use compiled bindings in DataTemplates,x:Bind in templates requires x:DataType,x:DataType on DataTemplate for compiled bindings,{Binding} in item templates for large lists,"<DataTemplate x:DataType=""local:Item""><TextBlock Text=""{x:Bind Name}""/></DataTemplate>","<DataTemplate><TextBlock Text=""{Binding Name}""/></DataTemplate>",High,https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
30,Performance,Profile with Visual Studio diagnostics,Measure before optimizing,Application Timeline and Memory Usage tools,Guessing at performance problems,"VS Diagnostic Tools > Application Timeline","Optimizing without profiling data",Medium,https://learn.microsoft.com/en-us/visualstudio/profiling/application-timeline
31,Threading,Use async/await for all IO,Keep UI thread responsive,async/await for file network and database operations,Synchronous IO blocking the UI thread,"var file = await StorageFile.GetFileFromPathAsync(path);","StorageFile.GetFileFromPathAsync(path).AsTask().Result;",High,https://learn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-universal-windows-platform-apps
32,Threading,Use CoreDispatcher for UI thread access,Post work back to the UI thread from background,Dispatcher.RunAsync from background threads,Touching UI elements from background threads,"await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => Status = ""Done"");","textBlock.Text = ""Done"" from Task.Run",High,https://learn.microsoft.com/en-us/uwp/api/windows.ui.core.coredispatcher
33,Threading,Offload CPU work with Task.Run,Keep compute-heavy work off UI thread,Task.Run for CPU-bound operations,Heavy computation blocking UI,"var result = await Task.Run(() => ProcessData(items));","var result = ProcessData(items); freezing UI",High,https://learn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-universal-windows-platform-apps
34,Threading,Use IProgress for status updates,Report progress from background operations,IProgress<T> for progress reporting to UI,Polling shared variables for progress,"var progress = new Progress<int>(p => ProgressBar.Value = p); await Task.Run(() => Process(progress));","while (!done) { await Task.Delay(100); check shared field; }",Medium,https://learn.microsoft.com/en-us/dotnet/api/system.progress-1
35,Adaptive,Use AdaptiveTrigger for responsive layouts,MinWindowWidth and MinWindowHeight triggers fire at standard breakpoints (640 small / 1008 medium),AdaptiveTrigger inside VisualState.StateTriggers with the 640 and 1008 breakpoints,Fixed layouts for a single screen size,"<VisualState.StateTriggers><AdaptiveTrigger MinWindowWidth=""640""/></VisualState.StateTriggers>","Single-column layout at all widths",High,https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml
36,Adaptive,Design for multiple device families,Phone tablet desktop Xbox and HoloLens,DeviceFamily-specific views and resources,Desktop-only design ignoring other form factors,"DeviceFamily-Mobile/MainPage.xaml for phone-specific layout","Fixed 1920x1080 layout",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/layout/screen-sizes-and-breakpoints-for-responsive-design
37,Adaptive,Use RelativePanel for adaptive positioning,Controls position relative to each other,RelativePanel for layouts that reflow at breakpoints,Absolute positioning or fixed margins,"<Button RelativePanel.Below=""title"" RelativePanel.AlignLeftWithPanel=""True""/>","<Button Margin=""0,60,0,0""/> calculated from title height",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml#relativepanel
38,Adaptive,Support multi-window with secondary views,Open detached views with CoreApplication.CreateNewView and ApplicationViewSwitcher,CreateNewView and TryShowAsStandaloneAsync for multi-document scenarios,Single-window assumptions when scenarios benefit from secondary views,"var view = CoreApplication.CreateNewView(); await view.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { /* set content */ });","Modal overlay used for content that should be a separate window",Medium,https://learn.microsoft.com/en-us/windows/uwp/design/layout/show-multiple-views
39,Accessibility,Set AutomationProperties,Enable Narrator and screen reader support,AutomationProperties.Name on all interactive controls,Controls without accessible names,"<AppBarButton AutomationProperties.Name=""Save document"" Icon=""Save""/>","<AppBarButton Icon=""Save""/> without name",High,https://learn.microsoft.com/en-us/windows/uwp/design/accessibility/basic-accessibility-information
40,Accessibility,Support keyboard and gamepad,All functions reachable without touch,Tab navigation XYFocus and access keys,Touch-only interactions,"<Button AccessKey=""S"" XYFocusDown=""{x:Bind OtherButton}""/>","No keyboard or gamepad support",High,https://learn.microsoft.com/en-us/windows/uwp/design/input/keyboard-interactions
41,Accessibility,Support contrast themes,Respect system contrast themes (renamed from high contrast in Windows 11),ThemeResource brushes that adapt to contrast themes,Hardcoded colors that vanish under contrast themes,"Foreground=""{ThemeResource SystemControlForegroundBaseHighBrush}""","Foreground=""#444444""",High,https://learn.microsoft.com/en-us/windows/uwp/design/accessibility/high-contrast-themes
42,Accessibility,Test with Narrator and Accessibility Insights,Validate screen reader and automation compliance,Regular Narrator walkthrough and Accessibility Insights scan,Shipping without accessibility testing,"Accessibility Insights FastPass on every page","No accessibility testing before release",Medium,https://accessibilityinsights.io/
43,Architecture,Use MVVM pattern,Separate View ViewModel and Model,ViewModel with INotifyPropertyChanged and ICommand,Business logic in code-behind,"ViewModel bound via DataContext with commands","MainPage.xaml.cs with database calls and UI logic",Medium,https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvm
44,Architecture,Use Template Studio for scaffolding,Proven project templates with navigation and services,Windows Template Studio for new UWP projects,Blank project with manual boilerplate,"Template Studio with MVVM Toolkit and navigation service","Blank App template building everything from scratch",Low,https://github.com/microsoft/TemplateStudio
45,Architecture,Use dependency injection,Register services for testability,Microsoft.Extensions.DI for service resolution,Static singletons and manual construction,"services.AddTransient<MainViewModel>(); services.AddSingleton<IDataService, DataService>();","DataService.Instance or new DataService() everywhere",Medium,https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection
46,Architecture,Keep platform APIs behind abstractions,Isolate WinRT APIs from business logic,Interfaces wrapping StorageFile FilePicker etc,Direct WinRT calls in ViewModels,"IFileService wrapping FileOpenPicker and StorageFile","FileOpenPicker usage directly in ViewModel",Medium,https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvm
47,Lifecycle,Handle suspend and resume,UWP apps are suspended when not in foreground,Save state in OnSuspending and restore in OnLaunched,Ignoring app lifecycle losing user state,"Application.Current.Suspending += (s, e) => SaveState();","No suspend handler losing in-progress form data",High,https://learn.microsoft.com/en-us/windows/uwp/launch-resume/app-lifecycle
48,Lifecycle,Use ExtendedExecutionSession for background work,Request extended time for unfinished operations,ExtendedExecutionSession for saving or uploads,Assuming background work completes after suspend,"var session = new ExtendedExecutionSession { Reason = ExtendedExecutionReason.SavingData };","Long upload with no extended execution that gets killed on suspend",Medium,https://learn.microsoft.com/en-us/windows/uwp/launch-resume/run-minimized-with-extended-execution
49,Lifecycle,Handle prelaunch,Apps must opt in to prelaunch via CoreApplication.EnablePrelaunch(true) starting in Windows 10 1607; check LaunchActivatedEventArgs.PrelaunchActivated to skip user-visible work,Opt in with EnablePrelaunch and skip heavy init when PrelaunchActivated is true,Performing full initialization or navigating during prelaunch,"CoreApplication.EnablePrelaunch(true); if (e.PrelaunchActivated) return; // skip heavy init","Loading all data and navigating on prelaunch",Medium,https://learn.microsoft.com/en-us/windows/uwp/launch-resume/handle-app-prelaunch
50,Testing,Unit test ViewModels,Test logic without UI framework dependencies,xUnit or MSTest on ViewModel methods,Testing only through the running app,"[Fact] public async Task Load_PopulatesItems() { await vm.LoadAsync(); Assert.NotEmpty(vm.Items); }","Manual testing by tapping through the app",Medium,https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
51,Testing,Use WinAppDriver with Appium for UI tests,Automated UI testing for UWP (Coded UI Test was deprecated in Visual Studio 2019); WinAppDriver v1 is in low-maintenance mode and Appium 2 is the modern direction,WinAppDriver with Appium for end-to-end tests,Manual regression testing,"session.FindElementByAccessibilityId(""SaveButton"").Click();","Manual click-through testing before each release",Medium,https://github.com/microsoft/WinAppDriver
52,Testing,Test on multiple device families,Behavior varies across phone desktop and Xbox,Test on device emulators and real hardware,Desktop-only testing,"Test on Mobile emulator and Xbox dev mode","Only running on local desktop",Medium,https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portal
53,Architecture,Prefer WinUI 3 for new projects,UWP is in maintenance mode and Microsoft recommends WinUI 3 and Windows App SDK for new development,WinUI 3 with Windows App SDK for new desktop apps,Starting new projects on UWP when WinUI 3 is available,"New project with Microsoft.WindowsAppSDK and WinUI 3","New UWP project for a desktop-only app in 2024+",Medium,https://learn.microsoft.com/en-us/windows/apps/get-started/
54,Architecture,Plan migration to Windows App SDK,Microsoft provides migration guides from UWP to WinUI 3,Incremental migration using XAML Islands or full port to WinUI 3,Ignoring migration path and accumulating UWP technical debt,"Follow UWP to WinUI 3 migration guide for existing apps","Continuing major feature development on UWP without migration plan",Medium,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/migrate-to-windows-app-sdk/overall-migration-strategy
55,Lifecycle,Use a deferral when saving async state on suspend,Suspending grants only ~5 seconds before the OS may terminate; await work needs SuspendingOperation.GetDeferral and Complete or save returns before it finishes,GetDeferral around async save calls and Complete in finally,Async work that returns the suspending handler before completion,"async void OnSuspending(object s, SuspendingEventArgs e) { var d = e.SuspendingOperation.GetDeferral(); try { await SaveAsync(); } finally { d.Complete(); } }","async void OnSuspending(object s, SuspendingEventArgs e) { await SaveAsync(); } // handler returns before save completes",Medium,https://learn.microsoft.com/en-us/windows/uwp/launch-resume/app-lifecycle
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 XAML Use x:Bind for compiled bindings Compile-time validated bindings with better performance x:Bind for type-safe performant bindings {Binding} when x:Bind is available <TextBlock Text="{x:Bind ViewModel.Name, Mode=OneWay}"/> <TextBlock Text="{Binding Name}"/> High https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
3 2 XAML Use x:Load for deferred elements Delay creation of elements until needed x:Load=False for hidden or conditional panels Loading all UI elements at page load <StackPanel x:Name="AdvancedPanel" x:Load="{x:Bind ShowAdvanced, Mode=OneWay}"> Collapsed StackPanel that is always instantiated Medium https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-load-attribute
4 3 XAML Use x:Phase for incremental item rendering Render list items in priority phases x:Phase on secondary content in item DataTemplates All template content loaded in one pass <TextBlock x:Phase="1" Text="{x:Bind Description}"/> Complex DataTemplate with no phasing Medium https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-phase-attribute
5 4 XAML Use x:DefaultBindMode Reduce repetitive Mode= declarations x:DefaultBindMode=OneWay on containers Mode=OneWay on every individual x:Bind <StackPanel x:DefaultBindMode="OneWay"> Mode=OneWay repeated on every binding in a panel Low https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
6 5 XAML Use x:DeferLoadStrategy for legacy support Deferred loading before x:Load was available x:Load (preferred) or x:DeferLoadStrategy=Lazy Eagerly loading rarely shown UI x:Load="False" (or x:DeferLoadStrategy="Lazy" on older targets) Always-loaded panels toggled with Visibility Low https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-deferloadstrategy-attribute
7 6 Controls Use NavigationView for app shell Standard UWP navigation pattern with hamburger menu NavigationView for top-level navigation Custom SplitView hamburger menu <NavigationView><NavigationView.MenuItems><NavigationViewItem Content="Home" Icon="Home"/></NavigationView.MenuItems></NavigationView> Custom SplitView with manual toggle button High https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/navigationview
8 7 Controls Use CommandBar for app actions Standard app bar for primary commands CommandBar with AppBarButtons Custom StackPanel toolbar <CommandBar><AppBarButton Icon="Save" Label="Save"/></CommandBar> <StackPanel Orientation="Horizontal"><Button>Save</Button></StackPanel> Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/command-bar
9 8 Controls Use ContentDialog for modals System-styled modal dialogs ContentDialog for confirmations and input Custom popup overlays <ContentDialog Title="Confirm" PrimaryButtonText="Yes" CloseButtonText="No"/> Grid overlay with manual focus trapping Medium https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/dialogs-and-flyouts/dialogs
10 9 Controls Use AutoSuggestBox for search Built-in search box with suggestions AutoSuggestBox with QuerySubmitted and SuggestionChosen TextBox with manual suggestion popup <AutoSuggestBox QueryIcon="Find" TextChanged="OnTextChanged" SuggestionChosen="OnChosen" QuerySubmitted="OnQuerySubmitted"/> TextBox with custom Popup and ListBox for suggestions Medium https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/auto-suggest-box
11 10 Controls Use CalendarDatePicker and TimePicker Platform-consistent date and time selection Built-in date and time pickers Custom date selection controls <CalendarDatePicker Header="Start date"/><TimePicker Header="Time"/> TextBox with date parsing and validation Low https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/date-and-time
12 11 Controls Use PersonPicture for user avatars Consistent avatar display with fallback initials PersonPicture with DisplayName and ProfilePicture Custom Ellipse with ImageBrush for avatars <PersonPicture DisplayName="Jane Doe" ProfilePicture="{x:Bind AvatarUri}"/> <Ellipse><Ellipse.Fill><ImageBrush ImageSource="avatar.png"/></Ellipse.Fill></Ellipse> Low https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/person-picture
13 12 Styling Use ThemeResource for adaptive colors Colors that switch with light and dark theme ThemeResource for all color references Hardcoded hex values that break in dark mode Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}" Foreground="#000000" High https://learn.microsoft.com/en-us/windows/uwp/design/style/color
14 13 Styling Use Fluent Design materials Acrylic translucent material for depth Built-in Fluent materials for depth and motion Custom shader effects for blur and reveal <Grid Background="{ThemeResource SystemControlAcrylicWindowBrush}"/> Custom CompositionEffectBrush recreating acrylic Medium https://learn.microsoft.com/en-us/windows/uwp/design/style/acrylic
15 14 Styling Use Lightweight Styling Override control resource keys for subtle changes Lightweight styling resource overrides Full ControlTemplate copy for small tweaks <Button><Button.Resources><SolidColorBrush x:Key="ButtonBackground" Color="Blue"/></Button.Resources></Button> Entire ControlTemplate copied to change background Medium https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/xaml-styles#lightweight-styling
16 15 Styling Use implicit styles for consistency TargetType without x:Key applies to all instances Implicit Style for default control appearance Repeating Setters on every control instance <Style TargetType="Button"><Setter Property="CornerRadius" Value="4"/></Style> CornerRadius="4" on every Button in the page Medium https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/xaml-styles
17 16 Styling Use VisualStateManager for visual states Define visual states with Setters that change properties when triggered VisualStateGroup containing VisualStates with Setter targets Toggling Visibility from code-behind on SizeChanged <VisualStateGroup><VisualState x:Name="Wide"><VisualState.Setters><Setter Target="root.Orientation" Value="Horizontal"/></VisualState.Setters></VisualState></VisualStateGroup> SizeChanged handler that flips Orientation in code-behind High https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml
18 17 Navigation Use Frame for page navigation Windows.UI.Xaml.Controls.Frame for UWP page navigation Frame.Navigate with typed parameters Swapping UserControls manually rootFrame.Navigate(typeof(DetailPage), itemId); contentArea.Content = new DetailPage(); Medium https://learn.microsoft.com/en-us/windows/uwp/design/basics/navigate-between-two-pages
19 18 Navigation Handle back button correctly Provide an in-app Back button styled with NavigationBackButtonNormalStyle and handle SystemNavigationManager.BackRequested for hardware back gamepad B and Tablet-Mode back; also handle CoreDispatcher.AcceleratorKeyActivated for Alt+Left In-app NavigationBackButtonNormalStyle button plus SystemNavigationManager.BackRequested handler Relying on the deprecated title-bar back button (AppViewBackButtonVisibility) or ignoring system back signals SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested; No back button support on phone or tablet High https://learn.microsoft.com/en-us/windows/uwp/ui-input/back-navigation
20 19 Navigation Support deep linking with protocol activation Respond to URI activation and toast taps OnActivated handler with proper page routing Ignoring activation arguments protected override void OnActivated(IActivatedEventArgs args) { if (args.Kind == ActivationKind.Protocol) { ... } } Empty OnActivated ignoring URI parameters Medium https://learn.microsoft.com/en-us/windows/uwp/launch-resume/handle-uri-activation
21 20 Navigation Use ConnectedAnimations for continuity Smooth transitions between pages ConnectedAnimationService for shared element transitions Abrupt page transitions with no visual continuity ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("image", sourceImage); No transition animation between list and detail Low https://learn.microsoft.com/en-us/windows/uwp/design/motion/connected-animation
22 21 Data Binding Implement INotifyPropertyChanged Enable UI updates on property changes INotifyPropertyChanged on all ViewModels Auto-properties without notification public string Title { get => _title; set { _title = value; OnPropertyChanged(); } } public string Title { get; set; } expecting UI updates High https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
23 22 Data Binding Use ObservableCollection for lists Collection change notifications for ItemsSources ObservableCollection<T> for bound lists List<T> for data-bound collections ObservableCollection<Item> Items { get; } = new(); List<Item> Items { get; set; } = new(); High https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
24 23 Data Binding Use function bindings with x:Bind Call static methods directly in markup x:Bind to static converter methods IValueConverter for trivial transforms <TextBlock Visibility="{x:Bind local:Converters.BoolToVisibility(IsActive), Mode=OneWay}"/> Full IValueConverter class for bool to Visibility Medium https://learn.microsoft.com/en-us/windows/uwp/data-binding/function-bindings
25 24 Data Binding Specify Mode on x:Bind x:Bind defaults to OneTime not OneWay Mode=OneWay or TwoWay when live updates needed Omitting Mode and getting stale UI Text="{x:Bind Title, Mode=OneWay}" Text="{x:Bind Title}" expecting live updates High https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
26 25 Data Binding Use CollectionViewSource for grouping Group and sort collections declaratively CollectionViewSource for grouped ListView and GridView Manual grouping logic in code-behind <CollectionViewSource x:Key="GroupedItems" IsSourceGrouped="True" Source="{x:Bind GroupedData}"/> Manual loop building grouped StackPanels Medium https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
27 26 Performance Use ListView and GridView virtualization Only creates containers for visible items Default virtualization in ListView and GridView Setting ItemsPanel to non-virtualizing panel <ListView ItemsSource="{x:Bind Items}"/> (virtualizes by default) <ListView><ListView.ItemsPanel><ItemsPanelTemplate><StackPanel/></ItemsPanelTemplate></ListView.ItemsPanel></ListView> High https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-gridview-and-listview
28 27 Performance Use ISupportIncrementalLoading Load data on demand as user scrolls ISupportIncrementalLoading for large datasets Loading entire collection upfront class IncrementalSource : ObservableCollection<Item>, ISupportIncrementalLoading await LoadAll() loading 50K items at startup Medium https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth
29 28 Performance Reduce XAML visual tree depth Simpler trees layout and render faster Flat templates with minimal nesting Deeply nested panels in DataTemplates <StackPanel><TextBlock/><TextBlock/></StackPanel> in item template <Grid><Border><StackPanel><Grid>... 8 levels in item template Medium https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-xaml-loading
30 29 Performance Use compiled bindings in DataTemplates x:Bind in templates requires x:DataType x:DataType on DataTemplate for compiled bindings {Binding} in item templates for large lists <DataTemplate x:DataType="local:Item"><TextBlock Text="{x:Bind Name}"/></DataTemplate> <DataTemplate><TextBlock Text="{Binding Name}"/></DataTemplate> High https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension
31 30 Performance Profile with Visual Studio diagnostics Measure before optimizing Application Timeline and Memory Usage tools Guessing at performance problems VS Diagnostic Tools > Application Timeline Optimizing without profiling data Medium https://learn.microsoft.com/en-us/visualstudio/profiling/application-timeline
32 31 Threading Use async/await for all IO Keep UI thread responsive async/await for file network and database operations Synchronous IO blocking the UI thread var file = await StorageFile.GetFileFromPathAsync(path); StorageFile.GetFileFromPathAsync(path).AsTask().Result; High https://learn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-universal-windows-platform-apps
33 32 Threading Use CoreDispatcher for UI thread access Post work back to the UI thread from background Dispatcher.RunAsync from background threads Touching UI elements from background threads await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => Status = "Done"); textBlock.Text = "Done" from Task.Run High https://learn.microsoft.com/en-us/uwp/api/windows.ui.core.coredispatcher
34 33 Threading Offload CPU work with Task.Run Keep compute-heavy work off UI thread Task.Run for CPU-bound operations Heavy computation blocking UI var result = await Task.Run(() => ProcessData(items)); var result = ProcessData(items); freezing UI High https://learn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-universal-windows-platform-apps
35 34 Threading Use IProgress for status updates Report progress from background operations IProgress<T> for progress reporting to UI Polling shared variables for progress var progress = new Progress<int>(p => ProgressBar.Value = p); await Task.Run(() => Process(progress)); while (!done) { await Task.Delay(100); check shared field; } Medium https://learn.microsoft.com/en-us/dotnet/api/system.progress-1
36 35 Adaptive Use AdaptiveTrigger for responsive layouts MinWindowWidth and MinWindowHeight triggers fire at standard breakpoints (640 small / 1008 medium) AdaptiveTrigger inside VisualState.StateTriggers with the 640 and 1008 breakpoints Fixed layouts for a single screen size <VisualState.StateTriggers><AdaptiveTrigger MinWindowWidth="640"/></VisualState.StateTriggers> Single-column layout at all widths High https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml
37 36 Adaptive Design for multiple device families Phone tablet desktop Xbox and HoloLens DeviceFamily-specific views and resources Desktop-only design ignoring other form factors DeviceFamily-Mobile/MainPage.xaml for phone-specific layout Fixed 1920x1080 layout Medium https://learn.microsoft.com/en-us/windows/uwp/design/layout/screen-sizes-and-breakpoints-for-responsive-design
38 37 Adaptive Use RelativePanel for adaptive positioning Controls position relative to each other RelativePanel for layouts that reflow at breakpoints Absolute positioning or fixed margins <Button RelativePanel.Below="title" RelativePanel.AlignLeftWithPanel="True"/> <Button Margin="0,60,0,0"/> calculated from title height Medium https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml#relativepanel
39 38 Adaptive Support multi-window with secondary views Open detached views with CoreApplication.CreateNewView and ApplicationViewSwitcher CreateNewView and TryShowAsStandaloneAsync for multi-document scenarios Single-window assumptions when scenarios benefit from secondary views var view = CoreApplication.CreateNewView(); await view.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { /* set content */ }); Modal overlay used for content that should be a separate window Medium https://learn.microsoft.com/en-us/windows/uwp/design/layout/show-multiple-views
40 39 Accessibility Set AutomationProperties Enable Narrator and screen reader support AutomationProperties.Name on all interactive controls Controls without accessible names <AppBarButton AutomationProperties.Name="Save document" Icon="Save"/> <AppBarButton Icon="Save"/> without name High https://learn.microsoft.com/en-us/windows/uwp/design/accessibility/basic-accessibility-information
41 40 Accessibility Support keyboard and gamepad All functions reachable without touch Tab navigation XYFocus and access keys Touch-only interactions <Button AccessKey="S" XYFocusDown="{x:Bind OtherButton}"/> No keyboard or gamepad support High https://learn.microsoft.com/en-us/windows/uwp/design/input/keyboard-interactions
42 41 Accessibility Support contrast themes Respect system contrast themes (renamed from high contrast in Windows 11) ThemeResource brushes that adapt to contrast themes Hardcoded colors that vanish under contrast themes Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}" Foreground="#444444" High https://learn.microsoft.com/en-us/windows/uwp/design/accessibility/high-contrast-themes
43 42 Accessibility Test with Narrator and Accessibility Insights Validate screen reader and automation compliance Regular Narrator walkthrough and Accessibility Insights scan Shipping without accessibility testing Accessibility Insights FastPass on every page No accessibility testing before release Medium https://accessibilityinsights.io/
44 43 Architecture Use MVVM pattern Separate View ViewModel and Model ViewModel with INotifyPropertyChanged and ICommand Business logic in code-behind ViewModel bound via DataContext with commands MainPage.xaml.cs with database calls and UI logic Medium https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvm
45 44 Architecture Use Template Studio for scaffolding Proven project templates with navigation and services Windows Template Studio for new UWP projects Blank project with manual boilerplate Template Studio with MVVM Toolkit and navigation service Blank App template building everything from scratch Low https://github.com/microsoft/TemplateStudio
46 45 Architecture Use dependency injection Register services for testability Microsoft.Extensions.DI for service resolution Static singletons and manual construction services.AddTransient<MainViewModel>(); services.AddSingleton<IDataService, DataService>(); DataService.Instance or new DataService() everywhere Medium https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection
47 46 Architecture Keep platform APIs behind abstractions Isolate WinRT APIs from business logic Interfaces wrapping StorageFile FilePicker etc Direct WinRT calls in ViewModels IFileService wrapping FileOpenPicker and StorageFile FileOpenPicker usage directly in ViewModel Medium https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvm
48 47 Lifecycle Handle suspend and resume UWP apps are suspended when not in foreground Save state in OnSuspending and restore in OnLaunched Ignoring app lifecycle losing user state Application.Current.Suspending += (s, e) => SaveState(); No suspend handler losing in-progress form data High https://learn.microsoft.com/en-us/windows/uwp/launch-resume/app-lifecycle
49 48 Lifecycle Use ExtendedExecutionSession for background work Request extended time for unfinished operations ExtendedExecutionSession for saving or uploads Assuming background work completes after suspend var session = new ExtendedExecutionSession { Reason = ExtendedExecutionReason.SavingData }; Long upload with no extended execution that gets killed on suspend Medium https://learn.microsoft.com/en-us/windows/uwp/launch-resume/run-minimized-with-extended-execution
50 49 Lifecycle Handle prelaunch Apps must opt in to prelaunch via CoreApplication.EnablePrelaunch(true) starting in Windows 10 1607; check LaunchActivatedEventArgs.PrelaunchActivated to skip user-visible work Opt in with EnablePrelaunch and skip heavy init when PrelaunchActivated is true Performing full initialization or navigating during prelaunch CoreApplication.EnablePrelaunch(true); if (e.PrelaunchActivated) return; // skip heavy init Loading all data and navigating on prelaunch Medium https://learn.microsoft.com/en-us/windows/uwp/launch-resume/handle-app-prelaunch
51 50 Testing Unit test ViewModels Test logic without UI framework dependencies xUnit or MSTest on ViewModel methods Testing only through the running app [Fact] public async Task Load_PopulatesItems() { await vm.LoadAsync(); Assert.NotEmpty(vm.Items); } Manual testing by tapping through the app Medium https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
52 51 Testing Use WinAppDriver with Appium for UI tests Automated UI testing for UWP (Coded UI Test was deprecated in Visual Studio 2019); WinAppDriver v1 is in low-maintenance mode and Appium 2 is the modern direction WinAppDriver with Appium for end-to-end tests Manual regression testing session.FindElementByAccessibilityId("SaveButton").Click(); Manual click-through testing before each release Medium https://github.com/microsoft/WinAppDriver
53 52 Testing Test on multiple device families Behavior varies across phone desktop and Xbox Test on device emulators and real hardware Desktop-only testing Test on Mobile emulator and Xbox dev mode Only running on local desktop Medium https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portal
54 53 Architecture Prefer WinUI 3 for new projects UWP is in maintenance mode and Microsoft recommends WinUI 3 and Windows App SDK for new development WinUI 3 with Windows App SDK for new desktop apps Starting new projects on UWP when WinUI 3 is available New project with Microsoft.WindowsAppSDK and WinUI 3 New UWP project for a desktop-only app in 2024+ Medium https://learn.microsoft.com/en-us/windows/apps/get-started/
55 54 Architecture Plan migration to Windows App SDK Microsoft provides migration guides from UWP to WinUI 3 Incremental migration using XAML Islands or full port to WinUI 3 Ignoring migration path and accumulating UWP technical debt Follow UWP to WinUI 3 migration guide for existing apps Continuing major feature development on UWP without migration plan Medium https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/migrate-to-windows-app-sdk/overall-migration-strategy
56 55 Lifecycle Use a deferral when saving async state on suspend Suspending grants only ~5 seconds before the OS may terminate; await work needs SuspendingOperation.GetDeferral and Complete or save returns before it finishes GetDeferral around async save calls and Complete in finally Async work that returns the suspending handler before completion async void OnSuspending(object s, SuspendingEventArgs e) { var d = e.SuspendingOperation.GetDeferral(); try { await SaveAsync(); } finally { d.Complete(); } } async void OnSuspending(object s, SuspendingEventArgs e) { await SaveAsync(); } // handler returns before save completes Medium https://learn.microsoft.com/en-us/windows/uwp/launch-resume/app-lifecycle

View File

@@ -0,0 +1,60 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,XAML,Use x:Bind for compiled bindings,Compile-time checked bindings with better performance,x:Bind for type-safe bindings,{Binding} when x:Bind works,"<TextBlock Text=""{x:Bind ViewModel.Title, Mode=OneWay}""/>","<TextBlock Text=""{Binding Title}""/>",High,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
2,XAML,Use x:Load for deferred loading,Only instantiate UI elements when needed,x:Load=False for hidden panels and dialogs,Loading all UI upfront,"<StackPanel x:Load=""{x:Bind ShowDetails, Mode=OneWay}"">","Always-loaded collapsed panels",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-load-attribute
3,XAML,Use x:Phase for incremental rendering,Load list items in phases for smooth scrolling,x:Phase on secondary content in DataTemplates,Loading all template content in phase 0,"<TextBlock x:Phase=""1"" Text=""{x:Bind Description}""/>","All content in single phase for complex templates",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
4,XAML,Use x:DefaultBindMode,Set default binding mode for a scope,x:DefaultBindMode=OneWay on containers with many bindings,Mode=OneWay on every individual x:Bind,"<StackPanel x:DefaultBindMode=""OneWay"">","Mode=OneWay repeated on 20 bindings",Low,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
5,Controls,Use NavigationView for app navigation,WinUI 3 NavigationView with Left Top and LeftCompact display modes plus footer items,NavigationView with PaneDisplayMode for main app shell,Custom hamburger menu implementation,"<NavigationView><NavigationView.MenuItems><NavigationViewItem Content=""Home""/></NavigationView.MenuItems></NavigationView>","Custom SplitView with manual hamburger button",High,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/navigationview
6,Controls,Use InfoBar for status messages,Non-intrusive informational messages,InfoBar for success warning and error messages,Custom styled StackPanel for status,"<InfoBar IsOpen=""True"" Severity=""Warning"" Title=""Update available""/>","<StackPanel Background=""Yellow""><TextBlock Text=""Warning""/></StackPanel>",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/infobar
7,Controls,Use TeachingTip for onboarding,Contextual tips attached to UI elements,TeachingTip for feature discovery,Custom popup for teaching,"<TeachingTip Target=""{x:Bind SearchBox}"" Title=""Try searching""/>","Custom Popup positioned near target element",Low,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/dialogs-and-flyouts/teaching-tip
8,Controls,Use ContentDialog for modal interactions,Standard modal dialog pattern,ContentDialog for confirmations and input,Custom overlay Panel as dialog,"<ContentDialog Title=""Delete?"" PrimaryButtonText=""Delete"" CloseButtonText=""Cancel""/>","Grid overlay with manual focus trapping",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/dialogs-and-flyouts/dialogs
9,Controls,Use BreadcrumbBar for hierarchy,Show navigation path in hierarchical apps,BreadcrumbBar for folder or category navigation,Manual TextBlock breadcrumb chain,"<BreadcrumbBar ItemsSource=""{x:Bind Breadcrumbs}""/>","<StackPanel Orientation=""Horizontal""><TextBlock Text=""Home > Settings > Display""/></StackPanel>",Low,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/breadcrumbbar
10,Styling,Use Lightweight Styling,Override control sub-properties via resources,Lightweight styling resource keys to tweak controls,Full ControlTemplate override for small changes,"<Button><Button.Resources><ResourceDictionary><ResourceDictionary.ThemeDictionaries><ResourceDictionary x:Key=""Light""><SolidColorBrush x:Key=""ButtonBackground"" Color=""MediumSlateBlue""/></ResourceDictionary></ResourceDictionary.ThemeDictionaries></ResourceDictionary></Button.Resources></Button>","Full ControlTemplate copy to change background color",High,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/xaml-styles#lightweight-styling
11,Styling,Use WinUI theme resources,Consistent Fluent Design colors and brushes,WinUI theme resource keys for colors,Hardcoded hex color values,"Background=""{ThemeResource CardBackgroundFillColorDefaultBrush}""","Background=""#FF2D2D30""",High,https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/color
12,Styling,Support light and dark themes,Respect user and system theme preference,ThemeResource for theme-adaptive values,Hardcoded colors that break in dark mode,"Foreground=""{ThemeResource TextFillColorPrimaryBrush}""","Foreground=""Black""",High,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/xaml-theme-resources
13,Styling,Use Fluent Design system,Acrylic Mica Reveal and rounded corners,Built-in Fluent materials and effects,Custom blur and shadow implementations,"<Grid Background=""{ThemeResource AcrylicInAppFillColorDefaultBrush}""/>","Custom CompositionBrush recreating acrylic",Medium,https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/materials
14,Navigation,Use Frame for page navigation,Microsoft.UI.Xaml.Controls.Frame for WinUI 3 page navigation,Frame.Navigate with page types and parameters,Swapping UserControls in a ContentControl,"rootFrame.Navigate(typeof(SettingsPage), parameter);","contentArea.Content = new SettingsControl();",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/navigation/navigate-between-two-pages
15,Navigation,Pass typed navigation parameters,Type-safe data passing between pages,Typed parameter in OnNavigatedTo,Dictionary or string parsing for parameters,"protected override void OnNavigatedTo(NavigationEventArgs e) { var item = (Item)e.Parameter; }","var id = int.Parse(e.Parameter.ToString());",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/navigation/navigate-between-two-pages
16,Navigation,Handle back navigation,WinUI 3 uses NavigationView.BackRequested instead of UWP SystemNavigationManager,Register NavigationView.BackRequested handler and manage back stack,"Ignoring back navigation","navigationView.BackRequested += OnBackRequested;","No back button support",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/navigation/navigation-history-and-backwards-navigation
17,Navigation,Use deep linking,Handle protocol activation so URIs route to the right page,Register protocol then check ExtendedActivationKind.Protocol on activation,Single entry point ignoring activation context,"AppInstance.GetCurrent().GetActivatedEventArgs() with ExtendedActivationKind.Protocol","Ignoring activation arguments",Medium,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle-rich-activation
18,Data Binding,Use ObservableCollection for lists,Notifies UI of collection changes,ObservableCollection<T> for bound ItemsSources,List<T> for bound collections,"ObservableCollection<Item> Items { get; } = new();","List<Item> Items { get; set; } = new();",High,https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth
19,Data Binding,Use INotifyPropertyChanged,Enable property change notification for UI updates,INotifyPropertyChanged on ViewModels,Properties without notification,"public string Name { get => _name; set => SetProperty(ref _name, value); }","public string Name { get; set; } without notification",High,https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth
20,Data Binding,Use function binding with x:Bind,Call methods directly in bindings,x:Bind with method references for transforms,IValueConverter for simple logic,"<TextBlock Visibility=""{x:Bind local:Converters.BoolToVisibility(IsActive), Mode=OneWay}""/>","IValueConverter class for bool to visibility",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/function-bindings
21,Data Binding,Specify Mode explicitly on x:Bind,x:Bind defaults to OneTime not OneWay,Mode=OneWay or Mode=TwoWay when updates needed,Forgetting Mode and getting stale UI,"Text=""{x:Bind Title, Mode=OneWay}""","Text=""{x:Bind Title}"" expecting live updates",High,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
22,Performance,Use ItemsRepeater for custom lists,Virtualizing layout with full control,ItemsRepeater for custom list layouts,ListView for highly customized item layouts,"<ItemsRepeater ItemsSource=""{x:Bind Items}""><ItemsRepeater.Layout><StackLayout/></ItemsRepeater.Layout></ItemsRepeater>","ListView with heavily modified template and removed chrome",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/items-repeater
23,Performance,Use incremental loading,Load data on demand as user scrolls,ISupportIncrementalLoading for large data sets,Loading entire dataset upfront,"class IncrementalItemSource : ObservableCollection<Item>, ISupportIncrementalLoading","await LoadAllItems() on page load for 10K items",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth
24,Performance,Reduce visual tree complexity,Simpler trees render faster,Minimal nesting in DataTemplates,Deeply nested panels in item templates,"<StackPanel><TextBlock/><TextBlock/></StackPanel>","<Grid><Border><StackPanel><Grid>... 8 levels deep",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/performance/optimize-xaml-loading
25,Performance,Use compiled bindings over reflection,x:Bind generates code at compile time,x:Bind for hot paths and list items,{Binding} in DataTemplates and frequently updated UI,"<DataTemplate x:DataType=""local:Item""><TextBlock Text=""{x:Bind Name}""/></DataTemplate>","<DataTemplate><TextBlock Text=""{Binding Name}""/></DataTemplate>",High,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
26,Threading,Use DispatcherQueue not Dispatcher,WinUI 3 uses Microsoft.UI.Dispatching.DispatcherQueue instead of UWP CoreDispatcher,DispatcherQueue.TryEnqueue for UI thread access,Dispatcher.RunAsync (UWP pattern),"_dispatcherQueue.TryEnqueue(() => Status = ""Done"");","Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ...);",High,https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.dispatching.dispatcherqueue
27,Threading,Use async/await for IO operations,Keep UI responsive during file and network access,async/await for IO so the UI thread keeps rendering,Synchronous IO on UI thread,"var data = await httpClient.GetStringAsync(url);","var data = httpClient.GetStringAsync(url).Result;",High,https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/
28,Threading,Use Task.Run for CPU-bound work,Offload compute to thread pool,Task.Run for heavy computation,Long-running CPU work on UI thread,"var result = await Task.Run(() => ProcessLargeDataSet());","var result = ProcessLargeDataSet(); blocking UI",High,https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming
29,Packaging,Use WinAppSDK correctly,Windows App SDK provides the runtime,WinAppSDK NuGet package and WindowsAppSDK bootstrapper,Mixing UWP and WinUI 3 APIs,"<PackageReference Include=""Microsoft.WindowsAppSDK""/>","Using Windows.UI.Xaml instead of Microsoft.UI.Xaml",High,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/
30,Packaging,Use unpackaged or packaged appropriately,Choose deployment model for your scenario,Packaged (MSIX) for Store distribution,Unpackaged without considering API limitations,"<WindowsPackageType>None</WindowsPackageType> for unpackaged","Assuming all APIs work in unpackaged mode",Medium,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/deploy-packaged-apps
31,Packaging,Use single-project MSIX,Simplified packaging for single app,Single-project MSIX packaging,Separate WAP project when not needed,"<EnableMsixTooling>true</EnableMsixTooling> in csproj","Separate Windows Application Packaging project for simple apps",Low,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/single-project-msix
32,Accessibility,Set AutomationProperties,Enable Narrator and screen reader support,AutomationProperties.Name on all interactive controls,Controls without accessible names,"<Button AutomationProperties.Name=""Save document""><FontIcon Glyph=""&#xE74E;""/></Button>","<Button><FontIcon Glyph=""&#xE74E;""/></Button> without name",High,https://learn.microsoft.com/en-us/windows/apps/design/accessibility/basic-accessibility-information
33,Accessibility,Support keyboard navigation,Full keyboard accessibility,Tab navigation and access keys for all controls,Mouse-only interactions,"<Button AccessKey=""S"" Content=""Save""/>","Interactive elements unreachable by keyboard",High,https://learn.microsoft.com/en-us/windows/apps/develop/input/keyboard-interactions
34,Accessibility,Use proper heading levels,Screen readers use headings for navigation,AutomationProperties.HeadingLevel on section headers,All text at same heading level,"<TextBlock AutomationProperties.HeadingLevel=""Level1"" Text=""Settings""/>","<TextBlock Style=""{StaticResource TitleTextBlockStyle}""/> without heading level",Medium,https://learn.microsoft.com/en-us/windows/apps/design/accessibility/basic-accessibility-information
35,Accessibility,Support high contrast,Respect system high contrast settings,ThemeResource brushes that adapt to high contrast,Hardcoded colors ignoring high contrast,"Foreground=""{ThemeResource TextFillColorPrimaryBrush}""","Foreground=""#333333""",High,https://learn.microsoft.com/en-us/windows/apps/design/accessibility/high-contrast-themes
36,Accessibility,Test with Accessibility Insights,Validate accessibility compliance,Accessibility Insights for Windows scanning,Manual accessibility checking only,"Run Accessibility Insights FastPass on every page","Ship without accessibility testing",Medium,https://accessibilityinsights.io/
37,Architecture,Use MVVM with CommunityToolkit,Source generators reduce boilerplate,[ObservableProperty] and [RelayCommand] attributes,Manual INotifyPropertyChanged and ICommand,"[ObservableProperty] private string _title; [RelayCommand] private void Save() { }","Full INotifyPropertyChanged implementation per property",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
38,Architecture,Use dependency injection,Register services with Microsoft.Extensions.DI,IServiceProvider for ViewModel and service resolution,new ViewModel() and new Service() everywhere,"services.AddTransient<MainViewModel>(); services.AddSingleton<IDataService, DataService>();","new MainViewModel(new DataService()) in code-behind",Medium,https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection/overview
39,Architecture,Use Template Studio patterns,Start with proven architectural templates,Template Studio for WinUI 3 project scaffolding,Blank project with manual setup for complex apps,"WinUI 3 Template Studio with MVVM and navigation","Blank App template for production app",Low,https://github.com/microsoft/TemplateStudio
40,Architecture,Separate platform from business logic,Keep business logic in .NET Standard or shared libraries,Business logic in separate class library,Business logic mixed with WinUI types,"Shared.Core project with no WinUI references","ViewModel importing Microsoft.UI.Xaml types",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
41,Architecture,Use WinUI 3 Window management,Proper window lifecycle management,AppWindow API for multi-window scenarios,Single Window assumption in complex apps,"var appWindow = this.AppWindow;","Relying solely on MainWindow for everything",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/manage-app-windows
42,Testing,Unit test ViewModels,Test logic independent of UI framework,xUnit or MSTest on ViewModel properties and commands,Testing through UI only,"[Fact] public async Task LoadItems_PopulatesCollection() { await vm.LoadCommand.ExecuteAsync(null); Assert.NotEmpty(vm.Items); }","Manual testing by running the app",Medium,https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
43,Testing,Use WinAppDriver for UI tests,Automated UI testing for WinUI 3,WinAppDriver or Appium for end-to-end tests,Manual regression testing,"var element = session.FindElementByAccessibilityId(""SaveButton""); element.Click();","Click-through manual testing",Medium,https://github.com/microsoft/WinAppDriver
44,Testing,Mock WinRT APIs in tests,Isolate tests from platform dependencies,Interface wrappers around WinRT APIs,Direct WinRT API calls in testable code,"IFileService wrapping StorageFile APIs","StorageFile.GetFileFromPathAsync directly in ViewModel",Medium,https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
45,Controls,Use NumberBox for numeric input,Built-in numeric entry with validation formatting and spin buttons,NumberBox with Minimum Maximum and SpinButtonPlacementMode,TextBox with manual numeric parsing and validation,"<NumberBox Value=""{x:Bind Quantity, Mode=TwoWay}"" Minimum=""0"" Maximum=""100"" SpinButtonPlacementMode=""Inline""/>","TextBox with regex validation for numbers",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/number-box
46,Controls,Use Expander for collapsible sections,Expandable content area with header for progressive disclosure,Expander for settings groups and optional content,Manual visibility toggling with buttons,"<Expander Header=""Advanced Settings""><StackPanel><ToggleSwitch Header=""Debug mode""/></StackPanel></Expander>","Button toggling StackPanel.Visibility for collapsible content",Low,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/expander
47,Controls,Use ProgressRing and ProgressBar for loading,Built-in loading indicators for determinate and indeterminate states,ProgressRing for indeterminate and ProgressBar for determinate progress,Custom spinning animation or text-based loading indicators,"<ProgressRing IsActive=""{x:Bind IsLoading, Mode=OneWay}""/>","<TextBlock Text=""Loading..."" Visibility=""{x:Bind IsLoading}""/>",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/progress-controls
48,Layout,Use VisualStateManager for responsive layouts,Adapt UI layout to window size using adaptive triggers,AdaptiveTrigger with MinWindowWidth for responsive breakpoints,Fixed layouts that break at different window sizes,"<VisualState><VisualState.StateTriggers><AdaptiveTrigger MinWindowWidth=""720""/></VisualState.StateTriggers><VisualState.Setters><Setter Target=""sidebar.Visibility"" Value=""Visible""/></VisualState.Setters></VisualState>","Fixed two-column layout at all window sizes",High,https://learn.microsoft.com/en-us/windows/apps/develop/ui/layouts-with-xaml
49,Lifecycle,Handle app activation and launch,WinUI 3 apps receive activation events for URI and notification launches,Check LaunchActivatedEventArgs in OnLaunched for activation context,Ignoring activation arguments losing deep link context,"protected override void OnLaunched(LaunchActivatedEventArgs args) { if (args.Arguments.Contains(""settings"")) NavigateToSettings(); }","Empty OnLaunched ignoring all activation parameters",Medium,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle-rich-activation
50,Lifecycle,Use single instancing with AppInstance,Prevent multiple app windows competing for resources,AppInstance.FindOrRegisterForKey for single-instance enforcement,Multiple instances with conflicting state,"var instance = AppInstance.FindOrRegisterForKey(""main""); if (!instance.IsCurrent) { await instance.RedirectActivationToAsync(args); }","No instance management allowing duplicate windows",Medium,https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle-instancing
51,Lifecycle,Save and restore app state,Persist UI state across app restarts for continuity (ApplicationData APIs require packaged apps; unpackaged apps must use file IO or registry),Save state to local settings on window close or navigation,Losing user context on every restart,"ApplicationData.Current.LocalSettings.Values[""lastPage""] = currentPage;","No state persistence losing navigation position on restart",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/data/store-and-retrieve-app-data
52,Styling,Choose Mica vs Acrylic by surface lifetime,Mica is for long-lived primary surfaces like main windows; Acrylic is for transient light-dismiss surfaces like flyouts and context menus,Mica on root window backgrounds and Acrylic on flyouts and overlays,Acrylic on the main window or Mica on transient flyouts,"<Window.SystemBackdrop><MicaBackdrop/></Window.SystemBackdrop> ... <FlyoutPresenter Background=""{ThemeResource AcrylicInAppFillColorDefaultBrush}""/>","Acrylic on every Window background causing battery and perf cost",Medium,https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/materials
53,Styling,Set SystemBackdrop on Window directly,WinUI 3 1.3+ exposes Window.SystemBackdrop with MicaBackdrop and DesktopAcrylicBackdrop classes replacing manual MicaController plumbing,Window.SystemBackdrop in XAML or code,Hand-rolled MicaController wiring when SystemBackdrop API is available,"<Window.SystemBackdrop><MicaBackdrop Kind=""Base""/></Window.SystemBackdrop>","var ctrl = new Microsoft.UI.Composition.SystemBackdrops.MicaController(); ctrl.AddSystemBackdropTarget(this.As<ICompositionSupportsSystemBackdrop>());",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/system-backdrops
54,Architecture,Open secondary windows with new Window,WinUI 3 supports multiple top-level windows; each Window owns an AppWindow accessible via Window.AppWindow for size and position control,new Window().Activate() for secondary windows tracking them in App state,Faking multi-window via main-window content swaps or ContentDialog,"var settings = new SettingsWindow(); settings.Activate();","MainWindow.Content = new SettingsView(); when a separate window is needed",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/ui/manage-app-windows
55,Architecture,Extend client area into the title bar,Use Window.ExtendsContentIntoTitleBar with SetTitleBar to host custom XAML in the chrome while preserving caption buttons,ExtendsContentIntoTitleBar=true plus SetTitleBar(element) for custom drag region,Hardcoded chrome height or custom caption buttons that break with theme and size changes,"this.ExtendsContentIntoTitleBar = true; this.SetTitleBar(AppTitleBar);","Padding=""0,32,0,0"" to reserve space without SetTitleBar leaves window non-draggable",Medium,https://learn.microsoft.com/en-us/windows/apps/develop/title-bar
56,Accessibility,Use KeyboardAccelerator for shortcuts,Map Ctrl/Alt/Shift combinations to commands using KeyboardAccelerator on UIElement,KeyboardAccelerator with Modifiers and Key on relevant controls,Manual KeyDown handlers swallowing shortcuts,"<Button Command=""{x:Bind SaveCommand}""><Button.KeyboardAccelerators><KeyboardAccelerator Modifiers=""Control"" Key=""S""/></Button.KeyboardAccelerators></Button>","Window.PreviewKeyDown=""OnKeyDown"" with switch over args.Key",High,https://learn.microsoft.com/en-us/windows/apps/develop/input/keyboard-accelerators
57,Styling,Organize resources with merged dictionaries,Share styles and brushes via App.xaml MergedDictionaries instead of duplicating per page,MergedDictionaries in App.xaml for shared styles brushes and colors,Duplicating SolidColorBrush definitions on every page,"<Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source=""Themes/Brushes.xaml""/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources>",SolidColorBrush Color hardcoded inline on every page,Medium,https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/xaml-resource-dictionary
58,Architecture,Use AsyncRelayCommand for async commands,AsyncRelayCommand exposes IsRunning and supports cancellation for IO bound work,[RelayCommand] on async Task method or AsyncRelayCommand for IO work,async void event handlers or fire-and-forget Task.Run from button click,"[RelayCommand] private async Task LoadAsync(CancellationToken ct) { Items = await _service.FetchAsync(ct); }","private async void Button_Click(object s, RoutedEventArgs e) { await LoadAsync(); }",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/asyncrelaycommand
59,Architecture,Use ILogger for structured logging,Microsoft.Extensions.Logging ILogger<T> with DI for structured leveled logs,ILogger<T> injected via constructor for diagnostic logging,Debug.WriteLine or Console.WriteLine for app diagnostics,"public MainViewModel(ILogger<MainViewModel> logger) { _logger = logger; } _logger.LogInformation(""Loaded {Count} items"", count);","Debug.WriteLine($""Loaded {count} items"");",Medium,https://learn.microsoft.com/en-us/dotnet/core/extensions/logging/overview
1 No Category Guideline Description Do Don't Code Good Code Bad Severity Docs URL
2 1 XAML Use x:Bind for compiled bindings Compile-time checked bindings with better performance x:Bind for type-safe bindings {Binding} when x:Bind works <TextBlock Text="{x:Bind ViewModel.Title, Mode=OneWay}"/> <TextBlock Text="{Binding Title}"/> High https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
3 2 XAML Use x:Load for deferred loading Only instantiate UI elements when needed x:Load=False for hidden panels and dialogs Loading all UI upfront <StackPanel x:Load="{x:Bind ShowDetails, Mode=OneWay}"> Always-loaded collapsed panels Medium https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-load-attribute
4 3 XAML Use x:Phase for incremental rendering Load list items in phases for smooth scrolling x:Phase on secondary content in DataTemplates Loading all template content in phase 0 <TextBlock x:Phase="1" Text="{x:Bind Description}"/> All content in single phase for complex templates Medium https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
5 4 XAML Use x:DefaultBindMode Set default binding mode for a scope x:DefaultBindMode=OneWay on containers with many bindings Mode=OneWay on every individual x:Bind <StackPanel x:DefaultBindMode="OneWay"> Mode=OneWay repeated on 20 bindings Low https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
6 5 Controls Use NavigationView for app navigation WinUI 3 NavigationView with Left Top and LeftCompact display modes plus footer items NavigationView with PaneDisplayMode for main app shell Custom hamburger menu implementation <NavigationView><NavigationView.MenuItems><NavigationViewItem Content="Home"/></NavigationView.MenuItems></NavigationView> Custom SplitView with manual hamburger button High https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/navigationview
7 6 Controls Use InfoBar for status messages Non-intrusive informational messages InfoBar for success warning and error messages Custom styled StackPanel for status <InfoBar IsOpen="True" Severity="Warning" Title="Update available"/> <StackPanel Background="Yellow"><TextBlock Text="Warning"/></StackPanel> Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/infobar
8 7 Controls Use TeachingTip for onboarding Contextual tips attached to UI elements TeachingTip for feature discovery Custom popup for teaching <TeachingTip Target="{x:Bind SearchBox}" Title="Try searching"/> Custom Popup positioned near target element Low https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/dialogs-and-flyouts/teaching-tip
9 8 Controls Use ContentDialog for modal interactions Standard modal dialog pattern ContentDialog for confirmations and input Custom overlay Panel as dialog <ContentDialog Title="Delete?" PrimaryButtonText="Delete" CloseButtonText="Cancel"/> Grid overlay with manual focus trapping Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/dialogs-and-flyouts/dialogs
10 9 Controls Use BreadcrumbBar for hierarchy Show navigation path in hierarchical apps BreadcrumbBar for folder or category navigation Manual TextBlock breadcrumb chain <BreadcrumbBar ItemsSource="{x:Bind Breadcrumbs}"/> <StackPanel Orientation="Horizontal"><TextBlock Text="Home > Settings > Display"/></StackPanel> Low https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/breadcrumbbar
11 10 Styling Use Lightweight Styling Override control sub-properties via resources Lightweight styling resource keys to tweak controls Full ControlTemplate override for small changes <Button><Button.Resources><ResourceDictionary><ResourceDictionary.ThemeDictionaries><ResourceDictionary x:Key="Light"><SolidColorBrush x:Key="ButtonBackground" Color="MediumSlateBlue"/></ResourceDictionary></ResourceDictionary.ThemeDictionaries></ResourceDictionary></Button.Resources></Button> Full ControlTemplate copy to change background color High https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/xaml-styles#lightweight-styling
12 11 Styling Use WinUI theme resources Consistent Fluent Design colors and brushes WinUI theme resource keys for colors Hardcoded hex color values Background="{ThemeResource CardBackgroundFillColorDefaultBrush}" Background="#FF2D2D30" High https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/color
13 12 Styling Support light and dark themes Respect user and system theme preference ThemeResource for theme-adaptive values Hardcoded colors that break in dark mode Foreground="{ThemeResource TextFillColorPrimaryBrush}" Foreground="Black" High https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/xaml-theme-resources
14 13 Styling Use Fluent Design system Acrylic Mica Reveal and rounded corners Built-in Fluent materials and effects Custom blur and shadow implementations <Grid Background="{ThemeResource AcrylicInAppFillColorDefaultBrush}"/> Custom CompositionBrush recreating acrylic Medium https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/materials
15 14 Navigation Use Frame for page navigation Microsoft.UI.Xaml.Controls.Frame for WinUI 3 page navigation Frame.Navigate with page types and parameters Swapping UserControls in a ContentControl rootFrame.Navigate(typeof(SettingsPage), parameter); contentArea.Content = new SettingsControl(); Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/navigation/navigate-between-two-pages
16 15 Navigation Pass typed navigation parameters Type-safe data passing between pages Typed parameter in OnNavigatedTo Dictionary or string parsing for parameters protected override void OnNavigatedTo(NavigationEventArgs e) { var item = (Item)e.Parameter; } var id = int.Parse(e.Parameter.ToString()); Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/navigation/navigate-between-two-pages
17 16 Navigation Handle back navigation WinUI 3 uses NavigationView.BackRequested instead of UWP SystemNavigationManager Register NavigationView.BackRequested handler and manage back stack Ignoring back navigation navigationView.BackRequested += OnBackRequested; No back button support Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/navigation/navigation-history-and-backwards-navigation
18 17 Navigation Use deep linking Handle protocol activation so URIs route to the right page Register protocol then check ExtendedActivationKind.Protocol on activation Single entry point ignoring activation context AppInstance.GetCurrent().GetActivatedEventArgs() with ExtendedActivationKind.Protocol Ignoring activation arguments Medium https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle-rich-activation
19 18 Data Binding Use ObservableCollection for lists Notifies UI of collection changes ObservableCollection<T> for bound ItemsSources List<T> for bound collections ObservableCollection<Item> Items { get; } = new(); List<Item> Items { get; set; } = new(); High https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth
20 19 Data Binding Use INotifyPropertyChanged Enable property change notification for UI updates INotifyPropertyChanged on ViewModels Properties without notification public string Name { get => _name; set => SetProperty(ref _name, value); } public string Name { get; set; } without notification High https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth
21 20 Data Binding Use function binding with x:Bind Call methods directly in bindings x:Bind with method references for transforms IValueConverter for simple logic <TextBlock Visibility="{x:Bind local:Converters.BoolToVisibility(IsActive), Mode=OneWay}"/> IValueConverter class for bool to visibility Medium https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/function-bindings
22 21 Data Binding Specify Mode explicitly on x:Bind x:Bind defaults to OneTime not OneWay Mode=OneWay or Mode=TwoWay when updates needed Forgetting Mode and getting stale UI Text="{x:Bind Title, Mode=OneWay}" Text="{x:Bind Title}" expecting live updates High https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
23 22 Performance Use ItemsRepeater for custom lists Virtualizing layout with full control ItemsRepeater for custom list layouts ListView for highly customized item layouts <ItemsRepeater ItemsSource="{x:Bind Items}"><ItemsRepeater.Layout><StackLayout/></ItemsRepeater.Layout></ItemsRepeater> ListView with heavily modified template and removed chrome Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/items-repeater
24 23 Performance Use incremental loading Load data on demand as user scrolls ISupportIncrementalLoading for large data sets Loading entire dataset upfront class IncrementalItemSource : ObservableCollection<Item>, ISupportIncrementalLoading await LoadAllItems() on page load for 10K items Medium https://learn.microsoft.com/en-us/windows/apps/develop/data-binding/data-binding-in-depth
25 24 Performance Reduce visual tree complexity Simpler trees render faster Minimal nesting in DataTemplates Deeply nested panels in item templates <StackPanel><TextBlock/><TextBlock/></StackPanel> <Grid><Border><StackPanel><Grid>... 8 levels deep Medium https://learn.microsoft.com/en-us/windows/apps/develop/performance/optimize-xaml-loading
26 25 Performance Use compiled bindings over reflection x:Bind generates code at compile time x:Bind for hot paths and list items {Binding} in DataTemplates and frequently updated UI <DataTemplate x:DataType="local:Item"><TextBlock Text="{x:Bind Name}"/></DataTemplate> <DataTemplate><TextBlock Text="{Binding Name}"/></DataTemplate> High https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/x-bind-markup-extension
27 26 Threading Use DispatcherQueue not Dispatcher WinUI 3 uses Microsoft.UI.Dispatching.DispatcherQueue instead of UWP CoreDispatcher DispatcherQueue.TryEnqueue for UI thread access Dispatcher.RunAsync (UWP pattern) _dispatcherQueue.TryEnqueue(() => Status = "Done"); Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ...); High https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.dispatching.dispatcherqueue
28 27 Threading Use async/await for IO operations Keep UI responsive during file and network access async/await for IO so the UI thread keeps rendering Synchronous IO on UI thread var data = await httpClient.GetStringAsync(url); var data = httpClient.GetStringAsync(url).Result; High https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/
29 28 Threading Use Task.Run for CPU-bound work Offload compute to thread pool Task.Run for heavy computation Long-running CPU work on UI thread var result = await Task.Run(() => ProcessLargeDataSet()); var result = ProcessLargeDataSet(); blocking UI High https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming
30 29 Packaging Use WinAppSDK correctly Windows App SDK provides the runtime WinAppSDK NuGet package and WindowsAppSDK bootstrapper Mixing UWP and WinUI 3 APIs <PackageReference Include="Microsoft.WindowsAppSDK"/> Using Windows.UI.Xaml instead of Microsoft.UI.Xaml High https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/
31 30 Packaging Use unpackaged or packaged appropriately Choose deployment model for your scenario Packaged (MSIX) for Store distribution Unpackaged without considering API limitations <WindowsPackageType>None</WindowsPackageType> for unpackaged Assuming all APIs work in unpackaged mode Medium https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/deploy-packaged-apps
32 31 Packaging Use single-project MSIX Simplified packaging for single app Single-project MSIX packaging Separate WAP project when not needed <EnableMsixTooling>true</EnableMsixTooling> in csproj Separate Windows Application Packaging project for simple apps Low https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/single-project-msix
33 32 Accessibility Set AutomationProperties Enable Narrator and screen reader support AutomationProperties.Name on all interactive controls Controls without accessible names <Button AutomationProperties.Name="Save document"><FontIcon Glyph="&#xE74E;"/></Button> <Button><FontIcon Glyph="&#xE74E;"/></Button> without name High https://learn.microsoft.com/en-us/windows/apps/design/accessibility/basic-accessibility-information
34 33 Accessibility Support keyboard navigation Full keyboard accessibility Tab navigation and access keys for all controls Mouse-only interactions <Button AccessKey="S" Content="Save"/> Interactive elements unreachable by keyboard High https://learn.microsoft.com/en-us/windows/apps/develop/input/keyboard-interactions
35 34 Accessibility Use proper heading levels Screen readers use headings for navigation AutomationProperties.HeadingLevel on section headers All text at same heading level <TextBlock AutomationProperties.HeadingLevel="Level1" Text="Settings"/> <TextBlock Style="{StaticResource TitleTextBlockStyle}"/> without heading level Medium https://learn.microsoft.com/en-us/windows/apps/design/accessibility/basic-accessibility-information
36 35 Accessibility Support high contrast Respect system high contrast settings ThemeResource brushes that adapt to high contrast Hardcoded colors ignoring high contrast Foreground="{ThemeResource TextFillColorPrimaryBrush}" Foreground="#333333" High https://learn.microsoft.com/en-us/windows/apps/design/accessibility/high-contrast-themes
37 36 Accessibility Test with Accessibility Insights Validate accessibility compliance Accessibility Insights for Windows scanning Manual accessibility checking only Run Accessibility Insights FastPass on every page Ship without accessibility testing Medium https://accessibilityinsights.io/
38 37 Architecture Use MVVM with CommunityToolkit Source generators reduce boilerplate [ObservableProperty] and [RelayCommand] attributes Manual INotifyPropertyChanged and ICommand [ObservableProperty] private string _title; [RelayCommand] private void Save() { } Full INotifyPropertyChanged implementation per property Medium https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
39 38 Architecture Use dependency injection Register services with Microsoft.Extensions.DI IServiceProvider for ViewModel and service resolution new ViewModel() and new Service() everywhere services.AddTransient<MainViewModel>(); services.AddSingleton<IDataService, DataService>(); new MainViewModel(new DataService()) in code-behind Medium https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection/overview
40 39 Architecture Use Template Studio patterns Start with proven architectural templates Template Studio for WinUI 3 project scaffolding Blank project with manual setup for complex apps WinUI 3 Template Studio with MVVM and navigation Blank App template for production app Low https://github.com/microsoft/TemplateStudio
41 40 Architecture Separate platform from business logic Keep business logic in .NET Standard or shared libraries Business logic in separate class library Business logic mixed with WinUI types Shared.Core project with no WinUI references ViewModel importing Microsoft.UI.Xaml types Medium https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
42 41 Architecture Use WinUI 3 Window management Proper window lifecycle management AppWindow API for multi-window scenarios Single Window assumption in complex apps var appWindow = this.AppWindow; Relying solely on MainWindow for everything Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/manage-app-windows
43 42 Testing Unit test ViewModels Test logic independent of UI framework xUnit or MSTest on ViewModel properties and commands Testing through UI only [Fact] public async Task LoadItems_PopulatesCollection() { await vm.LoadCommand.ExecuteAsync(null); Assert.NotEmpty(vm.Items); } Manual testing by running the app Medium https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
44 43 Testing Use WinAppDriver for UI tests Automated UI testing for WinUI 3 WinAppDriver or Appium for end-to-end tests Manual regression testing var element = session.FindElementByAccessibilityId("SaveButton"); element.Click(); Click-through manual testing Medium https://github.com/microsoft/WinAppDriver
45 44 Testing Mock WinRT APIs in tests Isolate tests from platform dependencies Interface wrappers around WinRT APIs Direct WinRT API calls in testable code IFileService wrapping StorageFile APIs StorageFile.GetFileFromPathAsync directly in ViewModel Medium https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
46 45 Controls Use NumberBox for numeric input Built-in numeric entry with validation formatting and spin buttons NumberBox with Minimum Maximum and SpinButtonPlacementMode TextBox with manual numeric parsing and validation <NumberBox Value="{x:Bind Quantity, Mode=TwoWay}" Minimum="0" Maximum="100" SpinButtonPlacementMode="Inline"/> TextBox with regex validation for numbers Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/number-box
47 46 Controls Use Expander for collapsible sections Expandable content area with header for progressive disclosure Expander for settings groups and optional content Manual visibility toggling with buttons <Expander Header="Advanced Settings"><StackPanel><ToggleSwitch Header="Debug mode"/></StackPanel></Expander> Button toggling StackPanel.Visibility for collapsible content Low https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/expander
48 47 Controls Use ProgressRing and ProgressBar for loading Built-in loading indicators for determinate and indeterminate states ProgressRing for indeterminate and ProgressBar for determinate progress Custom spinning animation or text-based loading indicators <ProgressRing IsActive="{x:Bind IsLoading, Mode=OneWay}"/> <TextBlock Text="Loading..." Visibility="{x:Bind IsLoading}"/> Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/progress-controls
49 48 Layout Use VisualStateManager for responsive layouts Adapt UI layout to window size using adaptive triggers AdaptiveTrigger with MinWindowWidth for responsive breakpoints Fixed layouts that break at different window sizes <VisualState><VisualState.StateTriggers><AdaptiveTrigger MinWindowWidth="720"/></VisualState.StateTriggers><VisualState.Setters><Setter Target="sidebar.Visibility" Value="Visible"/></VisualState.Setters></VisualState> Fixed two-column layout at all window sizes High https://learn.microsoft.com/en-us/windows/apps/develop/ui/layouts-with-xaml
50 49 Lifecycle Handle app activation and launch WinUI 3 apps receive activation events for URI and notification launches Check LaunchActivatedEventArgs in OnLaunched for activation context Ignoring activation arguments losing deep link context protected override void OnLaunched(LaunchActivatedEventArgs args) { if (args.Arguments.Contains("settings")) NavigateToSettings(); } Empty OnLaunched ignoring all activation parameters Medium https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle-rich-activation
51 50 Lifecycle Use single instancing with AppInstance Prevent multiple app windows competing for resources AppInstance.FindOrRegisterForKey for single-instance enforcement Multiple instances with conflicting state var instance = AppInstance.FindOrRegisterForKey("main"); if (!instance.IsCurrent) { await instance.RedirectActivationToAsync(args); } No instance management allowing duplicate windows Medium https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle-instancing
52 51 Lifecycle Save and restore app state Persist UI state across app restarts for continuity (ApplicationData APIs require packaged apps; unpackaged apps must use file IO or registry) Save state to local settings on window close or navigation Losing user context on every restart ApplicationData.Current.LocalSettings.Values["lastPage"] = currentPage; No state persistence losing navigation position on restart Medium https://learn.microsoft.com/en-us/windows/apps/develop/data/store-and-retrieve-app-data
53 52 Styling Choose Mica vs Acrylic by surface lifetime Mica is for long-lived primary surfaces like main windows; Acrylic is for transient light-dismiss surfaces like flyouts and context menus Mica on root window backgrounds and Acrylic on flyouts and overlays Acrylic on the main window or Mica on transient flyouts <Window.SystemBackdrop><MicaBackdrop/></Window.SystemBackdrop> ... <FlyoutPresenter Background="{ThemeResource AcrylicInAppFillColorDefaultBrush}"/> Acrylic on every Window background causing battery and perf cost Medium https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/materials
54 53 Styling Set SystemBackdrop on Window directly WinUI 3 1.3+ exposes Window.SystemBackdrop with MicaBackdrop and DesktopAcrylicBackdrop classes replacing manual MicaController plumbing Window.SystemBackdrop in XAML or code Hand-rolled MicaController wiring when SystemBackdrop API is available <Window.SystemBackdrop><MicaBackdrop Kind="Base"/></Window.SystemBackdrop> var ctrl = new Microsoft.UI.Composition.SystemBackdrops.MicaController(); ctrl.AddSystemBackdropTarget(this.As<ICompositionSupportsSystemBackdrop>()); Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/system-backdrops
55 54 Architecture Open secondary windows with new Window WinUI 3 supports multiple top-level windows; each Window owns an AppWindow accessible via Window.AppWindow for size and position control new Window().Activate() for secondary windows tracking them in App state Faking multi-window via main-window content swaps or ContentDialog var settings = new SettingsWindow(); settings.Activate(); MainWindow.Content = new SettingsView(); when a separate window is needed Medium https://learn.microsoft.com/en-us/windows/apps/develop/ui/manage-app-windows
56 55 Architecture Extend client area into the title bar Use Window.ExtendsContentIntoTitleBar with SetTitleBar to host custom XAML in the chrome while preserving caption buttons ExtendsContentIntoTitleBar=true plus SetTitleBar(element) for custom drag region Hardcoded chrome height or custom caption buttons that break with theme and size changes this.ExtendsContentIntoTitleBar = true; this.SetTitleBar(AppTitleBar); Padding="0,32,0,0" to reserve space without SetTitleBar leaves window non-draggable Medium https://learn.microsoft.com/en-us/windows/apps/develop/title-bar
57 56 Accessibility Use KeyboardAccelerator for shortcuts Map Ctrl/Alt/Shift combinations to commands using KeyboardAccelerator on UIElement KeyboardAccelerator with Modifiers and Key on relevant controls Manual KeyDown handlers swallowing shortcuts <Button Command="{x:Bind SaveCommand}"><Button.KeyboardAccelerators><KeyboardAccelerator Modifiers="Control" Key="S"/></Button.KeyboardAccelerators></Button> Window.PreviewKeyDown="OnKeyDown" with switch over args.Key High https://learn.microsoft.com/en-us/windows/apps/develop/input/keyboard-accelerators
58 57 Styling Organize resources with merged dictionaries Share styles and brushes via App.xaml MergedDictionaries instead of duplicating per page MergedDictionaries in App.xaml for shared styles brushes and colors Duplicating SolidColorBrush definitions on every page <Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="Themes/Brushes.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources> SolidColorBrush Color hardcoded inline on every page Medium https://learn.microsoft.com/en-us/windows/apps/develop/platform/xaml/xaml-resource-dictionary
59 58 Architecture Use AsyncRelayCommand for async commands AsyncRelayCommand exposes IsRunning and supports cancellation for IO bound work [RelayCommand] on async Task method or AsyncRelayCommand for IO work async void event handlers or fire-and-forget Task.Run from button click [RelayCommand] private async Task LoadAsync(CancellationToken ct) { Items = await _service.FetchAsync(ct); } private async void Button_Click(object s, RoutedEventArgs e) { await LoadAsync(); } Medium https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/asyncrelaycommand
60 59 Architecture Use ILogger for structured logging Microsoft.Extensions.Logging ILogger<T> with DI for structured leveled logs ILogger<T> injected via constructor for diagnostic logging Debug.WriteLine or Console.WriteLine for app diagnostics public MainViewModel(ILogger<MainViewModel> logger) { _logger = logger; } _logger.LogInformation("Loaded {Count} items", count); Debug.WriteLine($"Loaded {count} items"); Medium https://learn.microsoft.com/en-us/dotnet/core/extensions/logging/overview

View File

@@ -0,0 +1,57 @@
No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,XAML,Use XAML for declarative UI,Define layout and visuals in XAML not code-behind,XAML for structure and styling,Build UI trees in C# code-behind,"<Button Content=""Save"" Click=""OnSave""/>",var btn = new Button(); btn.Content = "Save";,Low,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/xaml/
2,XAML,Set x:Class on root element,Connects XAML to its code-behind partial class,x:Class on Window UserControl and Page,"Missing x:Class or mismatched namespace","<Window x:Class=""MyApp.MainWindow"">","<Window> without x:Class",High,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/xaml/
3,XAML,Use x:Name sparingly,Only name elements accessed from code-behind,x:Name when code-behind reference is needed,Naming every element,"<TextBox x:Name=""SearchBox""/>","x:Name on every control",Low,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/xaml/
4,XAML,Prefer attached properties for layout,Grid.Row Grid.Column DockPanel.Dock etc,Attached properties for panel positioning,Margin hacks for alignment,"<Button Grid.Row=""1"" Grid.Column=""2""/>","<Button Margin=""200,100,0,0""/>",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/properties/attached-properties-overview
5,XAML,Use routed events for tree-wide handling,Events bubble up or tunnel down the element tree letting parents handle child events with one handler,Handler at parent using TypeName.EventName syntax with e.Handled=true when consumed,Wiring identical handlers on every child when one parent handler suffices,"<StackPanel Button.Click=""OnAnyButtonClick"">","Click=""OnClick"" repeated on every Button under a common parent",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/events/routed-events-overview
6,Data Binding,Implement INotifyPropertyChanged,Enable UI updates when properties change,INotifyPropertyChanged on ViewModels,Public properties without notification,"public string Name { get => _name; set { if (_name != value) { _name = value; OnPropertyChanged(); } } }","public string Name { get; set; } without notification",High,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-implement-property-change-notification
7,Data Binding,Use ObservableCollection for lists,Notifies UI of add remove and reset,ObservableCollection<T> for bound collections,List<T> or Array for bound ItemsSources,"ObservableCollection<Item> Items { get; } = new();","List<Item> Items { get; set; } = new();",High,https://learn.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1
8,Data Binding,Set DataContext at the right level,Enables binding for the visual subtree,DataContext on Window or root container,DataContext on every child control,"<Window DataContext=""{Binding Source={StaticResource VM}}"">","Setting DataContext on each TextBlock individually",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/
9,Data Binding,Prefer Binding over code-behind assignments,Declarative binding keeps UI and logic separate,"{Binding Path=Name} in XAML","textBlock.Text = viewModel.Name in code-behind","<TextBlock Text=""{Binding Name}""/>","Loaded event handler that sets every property",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/data-binding-overview
10,Data Binding,Use UpdateSourceTrigger appropriately,Controls when source updates,PropertyChanged for instant feedback,Default LostFocus when search-as-you-type is needed,"Text=""{Binding Query, UpdateSourceTrigger=PropertyChanged}""","Text=""{Binding Query}"" when search-as-you-type needed",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-control-when-the-textbox-text-updates-the-source
11,Data Binding,Use IValueConverter for display transforms,Convert data for presentation without changing the model,IValueConverter for bool-to-visibility etc,Visibility properties on ViewModel,"<TextBlock Visibility=""{Binding IsActive, Converter={StaticResource BoolToVis}}""/>","public Visibility IsActiveVisibility => IsActive ? Visibility.Visible : Visibility.Collapsed;",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-convert-bound-data
12,Data Binding,Use INotifyDataErrorInfo for validation,Surface validation errors to the binding system instead of ad-hoc error UI,ObservableValidator with DataAnnotations attributes,Throwing in setters or maintaining separate error properties,"public partial class FormVm : ObservableValidator { [ObservableProperty][NotifyDataErrorInfo][Required] private string _email; }","if (string.IsNullOrEmpty(Email)) ErrorMessage = ""Required"";",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/observablevalidator
13,Layout,Use Grid for complex layouts,Rows and columns with proportional or fixed sizing,Grid with RowDefinitions and ColumnDefinitions,Canvas with absolute positions for forms,"<Grid><Grid.RowDefinitions><RowDefinition Height=""Auto""/><RowDefinition Height=""*""/></Grid.RowDefinitions></Grid>","<Canvas><TextBox Canvas.Left=""50"" Canvas.Top=""80""/></Canvas>",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/grid
14,Layout,Use StackPanel for linear content,Simple vertical or horizontal stacking,StackPanel for toolbars and simple lists,Grid with single column for linear content,"<StackPanel Orientation=""Horizontal""><Button/><Button/></StackPanel>","<Grid><Grid.RowDefinitions>..12 Auto rows..</Grid.RowDefinitions></Grid>",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/stackpanel
15,Layout,Use DockPanel for docked regions,Dock children to edges with last child filling,DockPanel for shell layouts (menu top sidebar left),Nested StackPanels to simulate docking,"<DockPanel><Menu DockPanel.Dock=""Top""/><TreeView DockPanel.Dock=""Left""/><Frame/></DockPanel>","Nested StackPanels with fixed widths for shell",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/dockpanel
16,Layout,Avoid hardcoded sizes,Use Auto Star and MinWidth/MaxWidth,Proportional sizing with * and Auto,Fixed pixel widths on resizable content,"<ColumnDefinition Width=""2*""/>","<ColumnDefinition Width=""350""/> on main content",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/grid
17,Layout,Use ScrollViewer for overflow,Wrap content that may exceed available space,ScrollViewer around long forms or lists,Clipping content without scroll,"<ScrollViewer><StackPanel>...long content...</StackPanel></ScrollViewer>","<StackPanel> that clips off-screen items",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/scrollviewer
18,Styling,Use Resource Dictionaries,Centralize colors brushes and styles,ResourceDictionary in App.xaml for theme values,Inline colors and font sizes on every element,"<SolidColorBrush x:Key=""PrimaryBrush"" Color=""#0078D4""/>","<Button Background=""#0078D4""/> repeated everywhere",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/systems/xaml-resources-overview
19,Styling,Use pack URIs for embedded resources,Reference embedded images fonts and resource dictionaries via the pack scheme,"pack://application:,,, syntax for cross-assembly assets",File-system paths for resources compiled into the assembly,"<Image Source=""pack://application:,,,/MyApp;component/Resources/icon.png""/>","<Image Source=""C:\Resources\icon.png""/>",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/app-development/pack-uris-in-wpf
20,Styling,Use implicit styles,Apply a Style to all instances of a TargetType,Style with TargetType and no x:Key for defaults,Manually styling every Button instance,"<Style TargetType=""Button""><Setter Property=""Padding"" Value=""12,6""/></Style>","Padding=""12,6"" on every Button",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/styles-templates-overview
21,Styling,Use explicit styles with x:Key and BasedOn,Named variant styles that inherit from a base via BasedOn,x:Key styles that BasedOn an implicit or named style,Duplicating setters across variants,"<Style x:Key=""PrimaryButton"" TargetType=""Button"" BasedOn=""{StaticResource {x:Type Button}}"">","Copy-pasting 10 Setters into a second Style",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/styles-templates-overview
22,Styling,Prefer StaticResource over DynamicResource,StaticResource is resolved once and faster,StaticResource for values that do not change at runtime,DynamicResource for static theme values,"Background=""{StaticResource PrimaryBrush}""","Background=""{DynamicResource PrimaryBrush}"" when theme never changes",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/systems/xaml-resources-overview
23,Styling,Use ControlTemplate for full control,Override default rendering of a control,ControlTemplate when built-in styles are insufficient,Nesting extra panels to hide the default template,"<ControlTemplate TargetType=""Button""><Border><ContentPresenter/></Border></ControlTemplate>","Wrapping Button in Border to fake a custom look",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/how-to-create-apply-template
24,Styling,Use DataTemplate for data presentation,Define how data objects render in ItemsControls,DataTemplate for ListBox ComboBox and ItemsControl items,ToString overrides for display,"<DataTemplate DataType=""{x:Type local:Person}""><TextBlock Text=""{Binding FullName}""/></DataTemplate>","Relying on ToString() in ListBox",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/data-templating-overview
25,Styling,Use Fluent theme on .NET 9+,ThemeMode applies the Windows 11 Fluent style; values are Light Dark System and None (default Aero2),ThemeMode on Application or Window,Legacy Aero2 styling for new Windows 11 apps,"<Application ThemeMode=""System"">","<Application> with default Aero2 look",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/whats-new/net90
26,Commands,Use ICommand for user actions,Decouple UI actions from logic,ICommand implementations (RelayCommand DelegateCommand),Click event handlers in code-behind,"<Button Command=""{Binding SaveCommand}""/>","<Button Click=""OnSaveClick""/> with logic in code-behind",High,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/commanding-overview
27,Commands,Use CanExecute for enable/disable,Automatically disable controls when action unavailable; call NotifyCanExecuteChanged when state changes,CanExecute returning false to disable buttons,IsEnabled binding to a separate bool,"new RelayCommand(Save, () => !IsBusy)","<Button IsEnabled=""{Binding IsNotBusy}""/>",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/commanding-overview
28,Commands,Use RelayCommand or DelegateCommand,Avoid implementing ICommand from scratch every time,RelayCommand (CommunityToolkit.Mvvm) or DelegateCommand (Prism),New ICommand class per command,"[RelayCommand] private void Save() { }","class SaveCommand : ICommand { ... } for each action",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/relaycommand
29,Commands,Use AsyncRelayCommand for async operations,Tracks IsRunning and disables the command while it executes preventing re-entry,AsyncRelayCommand or [RelayCommand] on async Task method,async void event handlers in code-behind,[RelayCommand] private async Task SaveAsync() { await _service.SaveAsync(); },"private async void OnSaveClick(object s, RoutedEventArgs e) { await _service.SaveAsync(); }",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/asyncrelaycommand
30,Commands,Use CommandParameter for context,Pass data from the UI element to the command handler,CommandParameter for item-specific actions,Relying on SelectedItem in every command,"<Button Command=""{Binding DeleteCommand}"" CommandParameter=""{Binding}""/>","Command handler accessing SelectedItem directly",Low,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/commanding-overview
31,Commands,Use InputBindings for keyboard shortcuts,Bind keyboard gestures to commands without manual key handling,KeyBinding inside Window.InputBindings,Custom key handling in PreviewKeyDown,"<Window.InputBindings><KeyBinding Key=""S"" Modifiers=""Ctrl"" Command=""{Binding SaveCommand}""/></Window.InputBindings>",PreviewKeyDown handler checking for Ctrl+S,Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/commanding-overview
32,Performance,Use VirtualizingStackPanel for large lists,Only creates UI elements for visible items. ListBox/ListView virtualize by default; TreeView requires opt-in,VirtualizingStackPanel.IsVirtualizing=True (set on TreeView; default for ListBox),Disabling virtualization on long lists,"<TreeView VirtualizingStackPanel.IsVirtualizing=""True"" VirtualizingStackPanel.VirtualizationMode=""Recycling""/>","<ListBox ScrollViewer.CanContentScroll=""False""/>",High,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/optimizing-performance-controls
33,Performance,Freeze Freezable objects,Frozen brushes and geometries skip change tracking,Freeze brushes and pens that do not change,Mutable brushes used as static resources,"var brush = new SolidColorBrush(Colors.Blue); brush.Freeze();","new SolidColorBrush() without Freeze in resources",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/freezable-objects-overview
34,Performance,Use DependencyProperty for custom-control binding targets,Binding target properties on custom controls must be DependencyProperties (sources can be plain CLR properties with INPC),Define DependencyProperty for properties bound TO on a custom control,Plain CLR properties as binding targets on custom controls,"public static readonly DependencyProperty NameProperty = ...","public string Name { get; set; } as binding target on custom control",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/properties/dependency-properties-overview
35,Performance,Use async for long operations,Keep UI thread responsive,async/await with Task.Run for CPU work,Synchronous operations that freeze the UI,"await Task.Run(() => HeavyComputation());","HeavyComputation() on UI thread",High,https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/
36,Performance,Profile with PerfView and Visual Studio,Measure before optimizing,Visual Studio diagnostic tools and PerfView,Guessing at performance bottlenecks,Performance Profiler in Visual Studio (Alt+F2),Optimize without profiling,Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/optimizing-wpf-application-performance
37,Threading,Use Dispatcher for UI updates,UI elements can only be accessed from the UI thread,Dispatcher.Invoke or BeginInvoke from background threads,Accessing UI elements from background threads,"Application.Current.Dispatcher.Invoke(() => Status = ""Done"");","textBlock.Text = ""Done"" from Task.Run",High,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/threading-model
38,Threading,Prefer async/await over Dispatcher,Modern async code returns to UI context automatically,async/await which resumes on captured SynchronizationContext,Manual Dispatcher.BeginInvoke for every callback,"var data = await LoadDataAsync(); Items = data;","Dispatcher.BeginInvoke(() => Items = result) in callback",Medium,https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/
39,Threading,Use Task.Run for CPU-bound work,Offload intensive work from UI thread,Task.Run for compute-bound work,Long-running computations on UI thread,"var result = await Task.Run(() => Compute());","var result = Compute(); on UI thread",High,https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming
40,Threading,Report progress from background tasks,Update UI with progress during long operations,IProgress<T> with Task.Run,Polling a shared variable for progress,"var progress = new Progress<int>(p => ProgressBar.Value = p); await Task.Run(() => Work(progress));","while (!done) { Thread.Sleep(100); check shared int; }",Medium,https://learn.microsoft.com/en-us/dotnet/api/system.progress-1
41,Threading,Handle DispatcherUnhandledException,Catch unhandled UI-thread exceptions to log them and prevent the default WPF crash dialog,Subscribe in App.xaml or App.OnStartup and set e.Handled=true after logging,Letting WPF show its default crash dialog and silently shut down,"<Application DispatcherUnhandledException=""App_OnUnhandledException"">",No global handler so any unhandled exception crashes the app,High,https://learn.microsoft.com/en-us/dotnet/api/system.windows.application.dispatcherunhandledexception
42,Accessibility,Set AutomationProperties,Enable screen reader support,AutomationProperties.Name on interactive controls,Controls without automation names,"<Button AutomationProperties.Name=""Save document""/>","<Button><Image Source=""save.png""/></Button> without name",High,https://learn.microsoft.com/en-us/dotnet/api/system.windows.automation.automationproperties
43,Accessibility,Support keyboard navigation,All functionality reachable via keyboard,Tab order and KeyboardNavigation properties,Mouse-only interactions,"<StackPanel KeyboardNavigation.TabNavigation=""Cycle"">","Click handlers with no keyboard equivalent",High,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/focus-overview
44,Accessibility,Support high contrast themes,Respect Windows high contrast settings,SystemColors and SystemFonts resources,Hardcoded colors that disappear in high contrast,"Foreground=""{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}""","Foreground=""#333333"" everywhere",Medium,https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/accessibility-best-practices
45,Accessibility,Use appropriate control types,Semantic controls convey role to assistive tech,Button for actions CheckBox for toggles,Styled TextBlock with click handler as fake button,"<Button Content=""Submit""/>","<TextBlock MouseDown=""OnSubmitClick"" Text=""Submit""/>",High,https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/accessibility-best-practices
46,Accessibility,Support DPI scaling,Ensure UI is crisp at all display scale factors,Device-independent units and vector graphics,Pixel-based bitmaps that blur at high DPI,"<Path Data=""M 10,10 L 20,20""/> or DrawingImage","<Image Source=""icon_32x32.png""/> at 200% scaling",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/graphics-multimedia/graphics
47,Accessibility,Declare PerMonitorV2 DPI awareness,WPF defaults to System-DPI-aware unless you opt into PerMonitorV2 via app.manifest,app.manifest with dpiAwareness PerMonitorV2,Default System DPI awareness for Windows 10/11 apps,"<dpiAwareness xmlns=""http://schemas.microsoft.com/SMI/2016/WindowsSettings"">PerMonitorV2</dpiAwareness>",No app.manifest leaving app at System DPI,Medium,https://learn.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
48,Architecture,Use MVVM pattern,Separate View ViewModel and Model concerns,MVVM with data binding and commands,Logic in code-behind,ViewModel with INotifyPropertyChanged and ICommand,MainWindow.xaml.cs with all business logic,High,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
49,Architecture,Override App.OnStartup for app initialization,Wire DI build the host resolve MainWindow and parse command-line args in OnStartup,Override OnStartup when DI or argument parsing is needed,Relying on StartupUri when MainWindow needs constructor injection,protected override void OnStartup(StartupEventArgs e) { _host.Start(); _host.Services.GetRequiredService<MainWindow>().Show(); },"<Application StartupUri=""MainWindow.xaml""/> when MainWindow has constructor dependencies",Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/app-development/application-management-overview
50,Architecture,Use dependency injection,Wire Microsoft.Extensions.Hosting Generic Host in App.OnStartup and resolve ViewModels from the container,Generic Host with Microsoft.Extensions.DependencyInjection,new Service() in ViewModel constructors,"services.AddTransient<MainViewModel>();","new MainViewModel(new DataService()) in App.xaml.cs",Medium,https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection/overview
51,Architecture,Use CommunityToolkit.Mvvm,Source generators reduce MVVM boilerplate,[ObservableProperty] and [RelayCommand] attributes,Hand-written INotifyPropertyChanged for every property,"[ObservableProperty] private string _name;","private string _name; public string Name { get ... set ... OnPropertyChanged ... }",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
52,Architecture,Keep code-behind minimal,Code-behind should only contain view-specific logic,View logic like focus management and animations in code-behind,Business logic and data access in code-behind,Loaded handler that sets initial focus,Loaded handler that calls database and populates grid,Medium,https://learn.microsoft.com/en-us/dotnet/desktop/wpf/xaml/
53,Architecture,Use messaging for loose coupling,Communicate between ViewModels without references,WeakReferenceMessenger from CommunityToolkit.Mvvm,Direct ViewModel-to-ViewModel references,"WeakReferenceMessenger.Default.Send(new ItemSavedMessage(item));","MainViewModel.Instance.RefreshItems() from DetailViewModel",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/messenger
54,Testing,Unit test ViewModels,Test business logic independent of UI,xUnit or NUnit tests on ViewModel methods and properties,Manual testing through the UI only,"[Fact] public void Save_WhenValid_SetsIsBusy() { vm.Save(); Assert.True(vm.IsBusy); }","Clicking buttons in the running app to verify",Medium,https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/
55,Testing,Mock services in tests,Isolate ViewModel from external dependencies,Moq or NSubstitute for service interfaces,Real database calls in unit tests,"var mock = new Mock<IDataService>(); var vm = new MainViewModel(mock.Object);","new MainViewModel(new SqlDataService()) in tests",Medium,https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
56,Testing,Use UI Automation for integration tests,Automated UI testing with Microsoft UI Automation,FlaUI or Appium 2 (appium-windows-driver) for end-to-end tests,Manual regression testing only,"AutomationElement.FindFirst(TreeScope.Children, condition)",Manual click-through testing,Medium,https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/ui-automation-overview
Can't render this file because it contains an unexpected character in line 2 and column 234.

View File

@@ -90,6 +90,11 @@ STACK_CONFIG = {
"angular": {"file": "stacks/angular.csv"},
"laravel": {"file": "stacks/laravel.csv"},
"javafx": {"file": "stacks/javafx.csv"},
"wpf": {"file": "stacks/wpf.csv"},
"winui": {"file": "stacks/winui.csv"},
"avalonia": {"file": "stacks/avalonia.csv"},
"uno": {"file": "stacks/uno.csv"},
"uwp": {"file": "stacks/uwp.csv"},
}
# Common columns for all stacks

View File

@@ -7,7 +7,7 @@ Usage: python search.py "<query>" [--domain <domain>] [--stack <stack>] [--max-r
python search.py "<query>" --design-system --persist [-p "Project Name"] [--page "dashboard"]
Domains: style, prompt, color, chart, landing, product, ux, typography, google-fonts
Stacks: react, nextjs, vue, svelte, astro, swiftui, react-native, flutter, nuxtjs, nuxt-ui, html-tailwind, shadcn, jetpack-compose, threejs, angular, laravel, javafx
Stacks: react, nextjs, vue, svelte, astro, swiftui, react-native, flutter, nuxtjs, nuxt-ui, html-tailwind, shadcn, jetpack-compose, threejs, angular, laravel, javafx, wpf, winui, avalonia, uno, uwp
Persistence (Master + Overrides pattern):
--persist Save design system to design-system/MASTER.md

View File

@@ -10,12 +10,12 @@
"scriptPath": "skills/ui-ux-pro-max/scripts/search.py",
"frontmatter": {
"name": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks."
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks."
},
"sections": {
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -13,6 +13,6 @@
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -10,12 +10,12 @@
"scriptPath": "skills/ui-ux-pro-max/scripts/search.py",
"frontmatter": {
"name": "ui-ux-pro-max",
"description": "UI/UX design intelligence. 67 styles, 161 palettes, 57 font pairings, 25 charts, 16 stacks (React, Next.js, Vue, Svelte, Astro, SwiftUI, React Native, Flutter, Nuxt, Nuxt UI, Tailwind, shadcn/ui, Jetpack Compose, Three.js, Angular, Laravel). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn/ui MCP for component search and examples."
"description": "UI/UX design intelligence. 67 styles, 161 palettes, 57 font pairings, 25 charts, 21 stacks (React, Next.js, Vue, Svelte, Astro, SwiftUI, React Native, Flutter, WPF, WinUI 3, UWP, Avalonia, Uno Platform, Nuxt, Nuxt UI, Tailwind, shadcn/ui, Jetpack Compose, Three.js, Angular, Laravel). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, desktop app, .html, .tsx, .vue, .svelte, .xaml. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn/ui MCP for component search and examples."
},
"sections": {
"quickReference": true
},
"title": "UI/UX Pro Max - Design Intelligence",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -16,6 +16,6 @@
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -16,6 +16,6 @@
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -16,6 +16,6 @@
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -10,12 +10,12 @@
"scriptPath": "prompts/ui-ux-pro-max/scripts/search.py",
"frontmatter": {
"name": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks."
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks."
},
"sections": {
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Workflow"
}

View File

@@ -10,12 +10,12 @@
"scriptPath": "skills/ui-ux-pro-max/scripts/search.py",
"frontmatter": {
"name": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks."
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks."
},
"sections": {
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -16,6 +16,6 @@
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -10,12 +10,12 @@
"scriptPath": "skills/ui-ux-pro-max/scripts/search.py",
"frontmatter": {
"name": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks."
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks."
},
"sections": {
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -10,12 +10,12 @@
"scriptPath": "steering/ui-ux-pro-max/scripts/search.py",
"frontmatter": {
"name": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks."
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks."
},
"sections": {
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Workflow"
}

View File

@@ -16,6 +16,6 @@
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -16,6 +16,6 @@
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -10,12 +10,12 @@
"scriptPath": "skills/ui-ux-pro-max/scripts/search.py",
"frontmatter": {
"name": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks."
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks."
},
"sections": {
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Workflow"
}

View File

@@ -16,6 +16,6 @@
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -13,6 +13,6 @@
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}

View File

@@ -10,12 +10,12 @@
"scriptPath": "skills/ui-ux-pro-max/scripts/search.py",
"frontmatter": {
"name": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks."
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks."
},
"sections": {
"quickReference": false
},
"title": "ui-ux-pro-max",
"description": "Comprehensive design guide for web and mobile applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 16 technology stacks. Searchable database with priority-based recommendations.",
"description": "Comprehensive design guide for web, mobile, and desktop applications. Contains 67 styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 22 technology stacks. Searchable database with priority-based recommendations.",
"skillOrWorkflow": "Skill"
}