This commit is contained in:
phaichayon
2026-07-02 10:20:45 +07:00
parent f7c9037ba4
commit bca8d3f7e0
147 changed files with 29838 additions and 0 deletions

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