Polish AmiReel UI and improve render workflow

This commit is contained in:
2026-08-11 13:55:44 +02:00
parent ad205bb534
commit d62ae0b9fb
38 changed files with 2711 additions and 183 deletions
@@ -0,0 +1,62 @@
---
description: 'Accessibility requirements for interactive controls, keyboard navigation, screen readers, and contrast'
applyTo: '**/*.cs, **/*.xaml'
---
# Accessibility
These rules apply to **every UI change**. They are not optional add-ons.
---
## Rules
- **Every interactive control** must have an `AutomationProperties.Name` or `AutomationProperties.LabeledBy`.
- Add a stable, unique `AutomationProperties.AutomationId` for controls targeted by UI automation tests (and for key interactive elements).
- Use semantic XAML controls — prefer `Button`, `HyperlinkButton`, `ListView` over styled `Border`/`Grid` with click handlers.
- Ensure **keyboard navigation** works for all features:
- Logical tab order via `TabIndex`.
- `AccessKey` bindings for frequently used actions.
- `KeyboardAccelerator` for shortcut keys.
- Maintain **minimum contrast ratios** (4.5:1 for normal text, 3:1 for large text) — test in High Contrast mode.
- Support **screen readers** (Narrator / NVDA): test that all content is announced correctly.
- Images must have `AutomationProperties.Name` describing the image purpose (or `AutomationProperties.AccessibilityView="Raw"` for decorative images).
- Do not rely on colour alone to convey meaning — add icons, text, or patterns.
## Anti-patterns
- Clickable `TextBlock` or `Image` without `AutomationProperties`.
- Custom controls that are not keyboard-focusable.
- Using `Visibility.Collapsed` to "hide" content from screen readers (use `AccessibilityView` instead).
## Validation
- Build & register the MSIX package — see **Build, Run & Deploy** in `.github/agents/Agents.md`.
- Test keyboard navigation: tab through every new/changed UI area.
- Test High Contrast: switch to Windows High Contrast theme and verify readability.
- Run Accessibility Insights for Windows on the app.
### Verification Checklist
- [ ] All interactive controls have `AutomationProperties.Name`
- [ ] Keyboard navigation works for the changed area
- [ ] Tested with High Contrast theme enabled
- [ ] Tab through the entire UI with keyboard only.
- [ ] Verify key interactive controls have stable, unique `AutomationProperties.AutomationId` values (especially controls used by UI automation tests).
- [ ] Switch to Windows High Contrast theme and verify readability.
- [ ] Run Narrator and verify all controls are announced correctly.
- [ ] Run **Accessibility Insights for Windows** on the app.
## Must Read & Research
> **Agent Rule:** Before any accessibility-related change, you **must** fetch and review these references using `fetch_webpage`. Apply what you learn.
| # | Reference | When to consult |
|---|---|---|
| 1 | [Accessibility in WinUI](https://learn.microsoft.com/en-us/windows/apps/design/accessibility/accessibility) | Any UI change — verify accessibility approach |
| 2 | [AutomationProperties](https://learn.microsoft.com/en-us/windows/apps/design/accessibility/basic-accessibility-information) | Adding or modifying interactive controls |
| 3 | [Accessibility Insights](https://accessibilityinsights.io/docs/windows/overview/) | Testing tool — run before finalizing UI changes |
| 4 | [Keyboard Accessibility](https://learn.microsoft.com/en-us/windows/apps/design/accessibility/keyboard-accessibility) | Adding navigation, focus management, or shortcut keys |
| 5 | [High Contrast Themes](https://learn.microsoft.com/en-us/windows/apps/design/accessibility/high-contrast-themes) | Adding custom styles, colours, or theme resources |
@@ -0,0 +1,170 @@
---
description: 'Static analysis, StyleCop, EditorConfig, naming conventions, and code cleanup rules'
applyTo: '**/*.cs, **/*.editorconfig, **/stylecop.json'
---
# Code Quality — Static Analysis, StyleCop & Code Cleanup
Maintain strict code quality through automated analysis and consistent style enforcement.
---
## 1. Static Analysis (Roslyn Analyzers)
### Required Analyzer Packages
Add these to the `.csproj` if not already present:
```xml
<ItemGroup>
<!-- Use the latest stable versions; do not hard-code version numbers in instructions -->
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="*" />
<PackageReference Include="StyleCop.Analyzers" Version="*">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
```
### Analysis Configuration in `.csproj`
```xml
<PropertyGroup>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisLevel>latest-recommended</AnalysisLevel>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
</PropertyGroup>
```
### Rule Enforcement
Follow **all** CA* (quality) and IDE* (code style) analyzer rules at their configured severity. Do not cherry-pick — obey every warning the analyzers report. When encountering a specific rule violation, fetch the corresponding documentation from the **Must Read & Research** references below to understand and apply the correct fix.
### `.editorconfig`
The project's `.editorconfig` in the solution root is the source of truth for code style. Obey all rules defined there. When creating or modifying `.editorconfig`, fetch the [EditorConfig Reference](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options) for the full list of available settings.
Key project conventions enforced via `.editorconfig`:
- Private fields use `_camelCase` prefix (SA1101 suppressed, SA1309 suppressed).
- File-scoped namespaces are required.
- `this.` qualification is not used.
---
## 2. StyleCop Rules
### StyleCop Configuration (`stylecop.json`)
Place this file in the project root alongside the `.csproj`:
```json
{
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"companyName": "YourProjectName",
"copyrightText": "Copyright (c) {companyName}. All rights reserved.",
"xmlHeader": false,
"documentInterfaces": true,
"documentExposedElements": true,
"documentInternalElements": false,
"documentPrivateElements": false,
"documentPrivateFields": false
},
"orderingRules": {
"usingDirectivesPlacement": "outsideNamespace",
"systemUsingDirectivesFirst": true
},
"layoutRules": {
"newlineAtEndOfFile": "require"
},
"namingRules": {
"allowCommonHungarianPrefixes": false
}
}
}
```
### Rule Enforcement
Follow **all** SA* (StyleCop) rules at their configured severity. When encountering a specific SA* violation, fetch the [StyleCop Rules Reference](https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/DOCUMENTATION.md) to understand the rule and apply the correct fix. Do not suppress rules without justification in a code comment.
---
## 3. Code Cleanup Rules (Always Enforced)
### After Every Edit
1. **Remove unused `using` statements** — No unused imports should remain.
2. **Remove commented-out code** — Version control tracks history; dead code is noise.
3. **Remove unused variables and fields** — If it's declared but never read, delete it.
4. **Remove empty methods** — If an event handler or override does nothing, remove it.
5. **Simplify code** — Apply IDE suggestions (IDE0001IDE0090) for:
- Removing unnecessary casts
- Simplifying `default` expressions
- Using pattern matching
- Using null-coalescing operators
### Naming Conventions
| Element | Convention | Example |
|---|---|---|
| Class / Struct | PascalCase | `MainViewModel` |
| Interface | I + PascalCase | `INavigationService` |
| Public method | PascalCase | `LoadDataAsync()` |
| Private method | PascalCase | `ValidateInput()` |
| Public property | PascalCase | `CurrentPage` |
| Private field | _camelCase | `_settingsService` |
| Parameter | camelCase | `userName` |
| Local variable | camelCase | `itemCount` |
| Constant | PascalCase | `MaxRetryCount` |
| Async method | Suffix `Async` | `FetchDataAsync()` |
| Boolean | Prefix `Is/Has/Can` | `IsLoading`, `HasAccess` |
### File Organization
Each `.cs` file should follow this order:
1. `using` directives (System first, then others, alphabetically)
2. Namespace declaration (file-scoped)
3. Class/struct/interface declaration
4. Inside the type:
1. Constants
2. Static fields
3. Instance fields
4. Constructors
5. Properties
6. Public methods
7. Private/internal methods
8. Event handlers
9. Nested types
---
## Validation
- Build & register the MSIX package — see **Build, Run & Deploy** in `.github/agents/Agents.md`.
- Fix **all** warnings — do not suppress without justification in a code comment.
- Verify no unused `using` statements remain after every edit.
- Verify no commented-out code remains.
- Confirm naming conventions match the table above for every new symbol.
---
## Must Read & Research
> **Agent Rule:** Before configuring analyzers, fixing warnings, or adjusting code style, you **must** fetch and review the relevant references below using `fetch_webpage`. Apply what you learn — do not skip this step.
| # | Reference | When to consult |
|---|---|---|
| 1 | [.NET Code Analysis Overview](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/overview) | Setting up or modifying analyzer configuration |
| 2 | [Code Style Rules (IDE0001IDE0090)](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/) | Resolving IDE* warnings or adjusting `.editorconfig` |
| 3 | [Quality Rules (CA*)](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/) | Resolving CA* warnings or suppressing with justification |
| 4 | [StyleCop.Analyzers GitHub](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) | Adding/updating StyleCop package or configuration |
| 5 | [StyleCop Rules Reference](https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/DOCUMENTATION.md) | Understanding specific SA* rule violations |
| 6 | [EditorConfig Reference](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options) | Modifying `.editorconfig` style or severity settings |
| 7 | [.NET Naming Conventions](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/identifier-names) | Verifying naming patterns for types, members, parameters |
@@ -0,0 +1,134 @@
---
description: 'Design principles (DRY, KISS, SOLID, YAGNI) enforced in every code change'
applyTo: '**/*.cs, **/*.xaml'
---
# Design Principles
Apply these principles in **every change** you make to this codebase. When in doubt, favour simplicity and clarity over cleverness.
---
## 1. DRY — Don't Repeat Yourself
> *"Every piece of knowledge must have a single, unambiguous, authoritative representation within a system."*
### Rules
- Before writing new code, **search** the codebase for existing implementations that solve the same problem.
- Extract shared logic into helper methods, base classes, or services.
- If you find duplicated code during a task, **refactor it** as part of the same change.
- Prefer generic/reusable components over copy-paste variations.
### Anti-patterns to avoid
- Copy-pasting code between classes/files instead of extracting a shared method.
- Creating multiple converters/helpers that do the same thing.
- Duplicating validation logic across ViewModel and Model layers.
---
## 2. KISS — Keep It Simple, Stupid
> *"Simplicity is the ultimate sophistication."*
### Rules
- Choose the **simplest approach** that meets the requirement.
- Avoid unnecessary abstractions, inheritance hierarchies, or patterns that add complexity without clear benefit.
- Write code that **reads like plain English** — favour descriptive names over comments.
- If a method is longer than ~30 lines, consider splitting it.
- If a class does more than one thing, split it (see SRP below).
### Anti-patterns to avoid
- Over-engineering with factories/builders/strategies for simple object creation.
- Creating deep inheritance trees when composition would suffice.
- Using complex LINQ chains when a simple `foreach` is clearer.
---
## 3. SOLID Principles
### 3.1 SRP — Single Responsibility Principle
> *"A class should have only one reason to change."*
- Each class/file should have **one clear responsibility**.
- ViewModels handle UI state & commands. Services handle business logic. Models hold data.
- If a class name contains "And" or "Manager", it likely violates SRP.
### 3.2 OCP — Open/Closed Principle
> *"Software entities should be open for extension, but closed for modification."*
- Use interfaces and abstract classes so behaviour can be extended without modifying existing code.
- Prefer adding new implementations over modifying existing ones.
- Use dependency injection to swap implementations.
### 3.3 LSP — Liskov Substitution Principle
> *"Objects of a superclass should be replaceable with objects of its subclasses without altering correctness."*
- Derived classes must honour the contracts of their base classes.
- Never throw `NotImplementedException` in overridden methods — if a subclass can't fulfil the contract, the inheritance is wrong.
### 3.4 ISP — Interface Segregation Principle
> *"No client should be forced to depend on methods it does not use."*
- Keep interfaces small and focused.
- Prefer multiple small interfaces over one large one.
- Example: `INavigationService`, `IDialogService`, `ISettingsService` — not `IAppService`.
### 3.5 DIP — Dependency Inversion Principle
> *"Depend upon abstractions, not concretions."*
- High-level modules must not depend on low-level modules. Both should depend on abstractions.
- Use constructor injection for dependencies.
- Register services in a DI container (e.g., `Microsoft.Extensions.DependencyInjection`).
---
## 4. YAGNI — You Aren't Gonna Need It
> *"Don't add functionality until it is necessary."*
### Rules
- Only implement what is **explicitly requested** or **clearly needed right now**.
- Do not add "just in case" parameters, methods, or abstractions.
- If you're unsure whether something is needed, **leave it out** — it can always be added later.
### Anti-patterns to avoid
- Adding unused interface methods "for future use".
- Building a generic framework when a single concrete class suffices.
- Creating configuration options nobody has asked for.
---
## Quick Reference Checklist
Before submitting any code change, verify:
- [ ] No duplicated code exists (DRY)
- [ ] The solution is as simple as possible (KISS)
- [ ] Each class has one responsibility (SRP)
- [ ] New behaviour is added via extension, not modification (OCP)
- [ ] Derived types can substitute their base types (LSP)
- [ ] Interfaces are small and focused (ISP)
- [ ] Dependencies point toward abstractions (DIP)
- [ ] No speculative features were added (YAGNI)
## Validation
- Review every new/changed class for SRP violations — ask "does this class have more than one reason to change?"
- Search the codebase for duplicate logic before adding new helpers: `grep_search` for similar method names or patterns.
- Verify no speculative code was added — every line must trace back to the original request.
- Build & register the MSIX package — see **Build, Run & Deploy** in `.github/agents/Agents.md`.
---
## Must Read & Research
> **Agent Rule:** Before making any code change related to design principles, you **must** fetch and review the relevant references below using `fetch_webpage`. Apply what you learn — do not skip this step.
| # | Reference | When to consult |
|---|---|---|
| 1 | [SOLID Principles in C# — Microsoft Learn](https://learn.microsoft.com/en-us/archive/msdn-magazine/2014/may/csharp-best-practices-dangers-of-violating-solid-principles-in-csharp) | Adding/refactoring classes, interfaces, or inheritance |
| 2 | [.NET Design Guidelines](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/) | Designing public APIs, naming, type design |
| 3 | [Framework Design Guidelines (Book)](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/) | Deep-dive on member design, exception patterns, collections |
| 4 | [Clean Code Summary](https://gist.github.com/wojteklu/73c6914cc446146b8b533c0988cf8d29) | Code readability, function size, naming clarity |
@@ -0,0 +1,55 @@
---
description: 'Globalization & Localization requirements for user-facing strings, resource files, and culture-aware formatting'
applyTo: '**/*.cs, **/*.xaml, **/*.resw'
---
# Globalization & Localization
These rules apply to **every feature and change** involving user-facing text. They are not optional add-ons.
---
## Rules
- **All user-facing strings** (UI text, error messages, tooltips) must come from `.resw` resource files — never hard-code them in XAML or C#.
- Resource file location: `Strings/en-us/Resources.resw` (default locale).
- Use `x:Uid` in XAML to bind controls to resource keys:
```xml
<TextBlock x:Uid="WelcomeMessage" />
```
With a matching `.resw` entry: `WelcomeMessage.Text` = "Welcome!"
- In code-behind / ViewModels, use the `ResourceLoader`:
```csharp
var loader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader();
string message = loader.GetString("ErrorFileNotFound");
```
- **Format dates, numbers, and currencies** using `CultureInfo.CurrentCulture` or `DateTimeFormatter` — never assume a specific regional format.
- Avoid concatenating translated strings — use format placeholders (`{0}`, `{1}`).
- Design UI layouts to accommodate text expansion (~30-40% longer for German vs. English).
## Anti-patterns
- Hard-coded strings in `.xaml` or `.cs` files (e.g., `Content="Save"`).
- Using `string.Format` with hard-coded ordinal assumptions.
- Fixed-width UI elements that clip translated text.
## Validation
- Build & register the MSIX package — see **Build, Run & Deploy** in `.github/agents/Agents.md`.
- Check for hard-coded strings: search `Content="` and `Text="` in `.xaml` files — replace with `x:Uid`.
### Verification Checklist
- [ ] All user-facing strings are in `.resw` resource files
## Must Read & Research
> **Agent Rule:** Before any localization-related change, you **must** fetch and review these references using `fetch_webpage`. Apply what you learn.
| # | Reference | When to consult |
|---|---|---|
| 1 | [Globalize your WinUI app](https://learn.microsoft.com/en-us/windows/apps/design/globalizing/guidelines-and-checklist-for-globalizing-your-app) | Adding any new user-facing strings or culture-aware formatting |
| 2 | [Resource Management System](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/mrtcore/localize-strings) | Setting up or modifying `.resw` files and `ResourceLoader` usage |
| 3 | [WinUI Localization with x:Uid](https://learn.microsoft.com/en-us/windows/apps/develop/ui-input/localizing-strings) | Binding XAML controls to localized resources via `x:Uid` |
@@ -0,0 +1,53 @@
---
description: 'Performance requirements for data binding, layout, threading, and collection virtualization'
applyTo: '**/*.cs, **/*.xaml'
---
# Performance
These rules apply to **every feature and change**. They are not optional add-ons.
---
## Rules
- **Use `x:Bind`** (compiled bindings) instead of `{Binding}` — it's faster and type-safe.
- Use **`x:Load`** (or `x:DeferLoadStrategy`) to defer loading of UI elements not immediately visible.
- Avoid heavy work on the UI thread — use `Task.Run` for CPU-bound work and `async/await` for I/O.
- Use **virtualizing panels** (`ItemsRepeater` with `StackLayout`, or `ListView`) for long lists — never use `StackPanel` with hundreds of items.
- **Cache** expensive computations and HTTP responses when appropriate.
- Minimize XAML visual tree depth — deep nesting hurts layout performance.
- Use **incremental loading** (`ISupportIncrementalLoading`) for large data sets.
- Profile with **Visual Studio Diagnostics Tools** and **PerfView** before and after optimizations.
- Be cautious with `DispatcherQueue.TryEnqueue` — don't flood the dispatcher queue.
## Anti-patterns
- Blocking the UI thread with `.Result` or `.GetAwaiter().GetResult()`.
- Loading all data upfront when only a subset is needed.
- Creating new `HttpClient` instances per request (use `IHttpClientFactory`).
- Using `FindName()` or `VisualTreeHelper` in tight loops.
## Validation
- Build & register the MSIX package — see **Build, Run & Deploy** in `.github/agents/Agents.md`.
### Verification Checklist
- [ ] No blocking calls on the UI thread
- [ ] `x:Bind` is used instead of `{Binding}`
- [ ] Large lists use virtualization
## Must Read & Research
> **Agent Rule:** Before any performance-sensitive change (data binding, layout, collections, async), you **must** fetch and review these references using `fetch_webpage`. Apply what you learn.
| # | Reference | When to consult |
|---|---|---|
| 1 | [Performance best practices for WinUI 3](https://learn.microsoft.com/en-us/windows/apps/performance/) | Any change touching UI rendering, data loading, or threading |
| 2 | [x:Bind markup extension](https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extension) | Adding or modifying XAML data bindings |
| 3 | [x:Load attribute](https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-load-attribute) | Deferring UI element loading |
| 4 | [Optimize XAML layout](https://learn.microsoft.com/en-us/windows/apps/performance/optimize-xaml-layout) | Restructuring XAML panels, reducing visual tree depth |
| 5 | [ListView optimization](https://learn.microsoft.com/en-us/windows/apps/performance/optimize-listview) | Working with lists, collections, or `ItemsRepeater` |
@@ -0,0 +1,55 @@
---
description: 'Security requirements for secrets management, input validation, permissions, and secure coding'
applyTo: '**/*.cs, **/*.appxmanifest'
---
# Security
These rules apply to **every feature and change**. They are not optional add-ons.
---
## Rules
- **Never hard-code secrets** (API keys, passwords, connection strings) — use environment variables, Windows Credential Manager, or Azure Key Vault.
- Validate and sanitize **all external input** (user input, file content, network responses).
- Use `SecureString` or `PasswordVault` for sensitive data in memory when practical.
- Follow the **principle of least privilege** — request only the permissions the app actually needs in `Package.appxmanifest`.
- Keep NuGet packages up to date — run `dotnet list package --outdated` regularly.
- Enable **code signing** for published MSIX packages. Use the `winapp` CLI rather than hand-rolling `signtool`:
- Generate a development certificate matching the manifest publisher: `winapp cert generate --manifest .\Package.appxmanifest --install`.
- Inspect a cert before signing: `winapp cert info .\devcert.pfx`.
- Sign an existing file: `winapp sign .\MyApp.msix --cert .\devcert.pfx`.
- Build + sign in one step: `winapp pack .\bin\<Platform>\Release\<TFM>\win-<rid> --cert .\devcert.pfx`.
- Production releases must be signed by a trusted certificate authority -- never ship the development cert.
- When using `HttpClient`, always validate TLS certificates and use HTTPS.
- Never log sensitive data (PII, tokens, passwords).
## Anti-patterns
- Storing secrets in `appsettings.json` committed to source control.
- Disabling TLS validation for debugging and forgetting to re-enable it.
- Using `Process.Start` with unsanitized user input.
- Broad `try { } catch (Exception) { }` that swallows errors silently without any logging.
## Validation
- Build & register the MSIX package — see **Build, Run & Deploy** in `.github/agents/Agents.md`.
- Check for hard-coded secrets: search for `password`, `apikey`, `secret`, `connectionstring` in `.cs` files.
### Verification Checklist
- [ ] No secrets are hard-coded
## Must Read & Research
> **Agent Rule:** Before any security-related change (auth, input handling, permissions, HTTP), you **must** fetch and review these references using `fetch_webpage`. Apply what you learn.
| # | Reference | When to consult |
|---|---|---|
| 1 | [.NET Security Best Practices](https://learn.microsoft.com/en-us/dotnet/standard/security/) | Any code handling credentials, tokens, or sensitive data |
| 2 | [Secure coding guidelines for .NET](https://learn.microsoft.com/en-us/dotnet/standard/security/secure-coding-guidelines) | Input validation, exception handling, type safety |
| 3 | [MSIX Security](https://learn.microsoft.com/en-us/windows/msix/msix-container) | Packaging, signing, or distribution changes |
| 4 | [Package.appxmanifest capabilities](https://learn.microsoft.com/en-us/windows/uwp/packaging/app-capability-declarations) | Adding or modifying app capabilities/permissions |
@@ -0,0 +1,284 @@
---
description: 'Unit testing standards, test project setup, naming, build & run commands'
applyTo: '**/*Tests.cs, **/*Test.cs, **/*.Tests.csproj'
---
# Testing — Unit Tests, Build & Run
Every public method and class must have corresponding unit tests. Tests are not optional.
---
## 1. Test Framework & Project Setup
### Recommended Stack
| Component | Package | Purpose |
|---|---|---|
| Test Framework | `MSTest` | Test runner & assertions |
| Mocking | `Moq` | Mock dependencies |
| UI Testing | `Microsoft.Windows.Apps.Test` | WinUI UI automation (optional) |
### Test Project Setup
Create a test project alongside the main project:
```
<SolutionRoot>/
<ProjectName>/ ← Main app project
<ProjectName>.Tests/ ← Unit test project
```
Test project `.csproj` should reference the main project:
```xml
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Match TargetFramework to the main project's .csproj -->
<TargetFramework><!-- same as the main project's .csproj TargetFramework --></TargetFramework>
<UseWinUI>true</UseWinUI>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<!-- Use latest stable versions; do not hard-code version numbers in instructions -->
<PackageReference Include="MSTest.TestAdapter" Version="*" />
<PackageReference Include="MSTest.TestFramework" Version="*" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="*" />
<PackageReference Include="Moq" Version="*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\<ProjectName>\<ProjectName>.csproj" />
</ItemGroup>
</Project>
```
---
## 2. Test Writing Rules
### What to Test
- **All public methods** in ViewModels, Services, Helpers, and Models.
- **Edge cases** — null inputs, empty collections, boundary values.
- **Error paths** — exception handling, invalid state transitions.
- **Business logic** — calculations, transformations, state management.
### What NOT to Test (Directly)
- XAML layout / visual rendering (use UI tests for that).
- Framework internals (e.g., `InitializeComponent()`).
- Private methods — test them indirectly through public methods.
### Test Naming Convention
Use the pattern: `MethodName_Scenario_ExpectedResult`
```csharp
[TestMethod]
public void CalculateTotal_WithEmptyCart_ReturnsZero() { }
[TestMethod]
public void LoadDataAsync_WhenServiceThrows_SetsErrorState() { }
[TestMethod]
public async Task SaveAsync_WithValidInput_ReturnsTrue() { }
```
### Test Structure (AAA Pattern)
Every test follows **Arrange → Act → Assert**:
```csharp
[TestMethod]
public void Add_TwoPositiveNumbers_ReturnsSum()
{
// Arrange
var calculator = new Calculator();
// Act
int result = calculator.Add(2, 3);
// Assert
Assert.AreEqual(5, result);
}
```
### ViewModel Testing Example
```csharp
[TestMethod]
public async Task LoadItemsAsync_OnSuccess_PopulatesItems()
{
// Arrange
var mockService = new Mock<IDataService>();
mockService
.Setup(s => s.GetItemsAsync())
.ReturnsAsync(new List<Item> { new("Test") });
var viewModel = new MainViewModel(mockService.Object);
// Act
await viewModel.LoadItemsAsync();
// Assert
Assert.AreEqual(1, viewModel.Items.Count);
Assert.IsFalse(viewModel.IsLoading);
}
```
---
## 3. Test Organization
### File Structure
Mirror the main project's folder structure (defined in [winui-best-practices](winui-best-practices.instructions.md)) in the test project. As the main project grows with subfolders under `ViewModels/`, `Services/`, `Views/`, etc., the test project must grow organically in the same way. This alignment enables on-demand test runs scoped to the area you changed:
```
<ProjectName>/ <ProjectName>.Tests/
Models/ Models/
User.cs UserTests.cs
ViewModels/ ViewModels/
MainViewModelTests.cs MainViewModelTests.cs
Settings/ Settings/
ThemeViewModel.cs ThemeViewModelTests.cs
Services/ Services/
DataService.cs DataServiceTests.cs
Auth/ Auth/
AuthService.cs AuthServiceTests.cs
Helpers/ Helpers/
StringHelper.cs StringHelperTests.cs
Converters/ Converters/
BoolToVisibilityConverter.cs BoolToVisibilityConverterTests.cs
```
### One Test Class per Class Under Test
```csharp
namespace <RootNamespace>.Tests.ViewModels;
[TestClass]
public class MainViewModelTests
{
// All tests for MainViewModel go here
}
```
### Running Tests On-Demand
After a change, run only the tests related to the affected area instead of the full suite. Detect the platform first (matching the convention in `.github/agents/Agents.md`):
```powershell
# Run from the test project folder
cd <ProjectName>.Tests
# Detect platform once per session (AMD64 -> x64; ARM64/x86 unchanged)
$arch = $env:PROCESSOR_ARCHITECTURE
$Platform = if ($arch -eq 'AMD64') { 'x64' } else { $arch }
# Run tests for a specific class
dotnet test -c Debug -p:Platform=$Platform --filter "FullyQualifiedName~MainViewModelTests"
# Run a single test
dotnet test -c Debug -p:Platform=$Platform --filter "FullyQualifiedName~MainViewModelTests.LoadItemsAsync_OnSuccess_PopulatesItems"
# Run all tests in a namespace (e.g., all ViewModel tests)
dotnet test -c Debug -p:Platform=$Platform --filter "FullyQualifiedName~Tests.ViewModels"
# Run tests in a subfolder namespace (e.g., only Settings ViewModels)
dotnet test -c Debug -p:Platform=$Platform --filter "FullyQualifiedName~Tests.ViewModels.Settings"
# Run the full suite (for cross-cutting changes)
dotnet test -c Debug -p:Platform=$Platform
```
```
---
## 4. Test-Specific Commands
For general build and register commands, see **Build, Run & Deploy** in `.github/agents/Agents.md`.
For on-demand test filtering, see **Running Tests On-Demand** above.
Below are additional test commands:
### Build Only the Test Project
```powershell
cd <ProjectName>.Tests
$arch = $env:PROCESSOR_ARCHITECTURE
$Platform = if ($arch -eq 'AMD64') { 'x64' } else { $arch }
dotnet build -c Debug -p:Platform=$Platform
```
### Run Tests with Verbose Output
```powershell
dotnet test -c Debug -p:Platform=$Platform --verbosity normal
```
---
## 5. Agent Workflow for Tests
When you write or modify code, follow this sequence:
1. **Implement the feature or fix** in the main project.
2. **Write unit tests** for every new/changed public method.
3. **Build** — see **Build, Run & Deploy** in `.github/agents/Agents.md`. Fix all errors and warnings.
4. **Run tests**`dotnet test -c Debug -p:Platform=$Platform` (from the test project folder; detect `$Platform` as shown above) and ensure all pass.
5. **Review** — Confirm tests cover the happy path, edge cases, and error cases.
### When Modifying Existing Code
1. **Run existing tests first** to establish a baseline.
2. Make the code change.
3. **Run tests again** — fix any failures.
4. **Add new tests** if the change introduces new behaviour.
### Coverage Goals
- Aim for **80%+ code coverage** on business logic (ViewModels, Services).
- 100% coverage of utility/helper methods.
- UI code-behind is exempt from unit test coverage (tested via integration/UI tests).
---
## 6. Common Test Pitfalls
| Pitfall | Fix |
|---|---|
| Test depends on another test's state | Each test must be fully independent |
| Testing multiple things in one test | One assertion per logical concept |
| Tests pass but don't actually verify anything | Always have meaningful assertions |
| Mocking too much | Mock only external dependencies, not the class under test |
| Testing implementation details | Test behaviour and outcomes, not internal method calls |
| Async tests without `await` | Always `await` async methods and use `async Task` return type |
---
## Validation
- Build & run tests — see **Build, Run & Deploy** in `.github/agents/Agents.md`.
- Verify all tests pass — zero failures, zero skipped without justification.
- Verify naming follows `MethodName_Scenario_ExpectedResult` pattern.
- Verify AAA structure (Arrange/Act/Assert) in every test method.
- Confirm coverage goals: 80%+ on ViewModels/Services, 100% on helpers.
---
## Must Read & Research
> **Agent Rule:** Before writing or modifying tests, you **must** fetch and review the relevant references below using `fetch_webpage`. Apply what you learn — do not skip this step.
| # | Reference | When to consult |
|---|---|---|
| 1 | [Unit testing C# with MSTest](https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-mstest) | Setting up test project, writing first tests, MSTest attributes |
| 2 | [Unit testing best practices .NET](https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices) | Every time you write tests — naming, structure, AAA pattern |
| 3 | [Moq Quickstart](https://github.com/devlooped/moq/wiki/Quickstart) | Mocking interfaces, setting up `Returns`/`Throws`, verifying calls |
| 4 | [FluentAssertions Documentation](https://fluentassertions.com/introduction) | Writing expressive assertions (`Should().Be()`, collections, exceptions) |
| 5 | [dotnet test CLI](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test) | Running tests from terminal, filtering, verbosity options |
| 6 | [Test Explorer in Visual Studio](https://learn.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer) | Debugging tests, viewing coverage, understanding test output |
@@ -0,0 +1,92 @@
---
description: 'WinAppSDK & Windows Platform SDK -- API namespace catalog and lookup guidance'
applyTo: '**/*.cs, **/*.xaml, **/*.csproj'
---
# Windows APIs -- WinAppSDK & Windows Platform SDK
## Sample-First Rule
> **Agent Rule -- MANDATORY:** Before implementing **any** WinAppSDK or Windows Platform SDK API you have not used before, you **must** search the sample repositories below for a working example first. **Do not guess API usage patterns from documentation alone** -- the docs often omit critical details that only the sample code reveals. Search **all** of the following repos, not just one:
| # | Repository | What it covers |
|---|---|---|
| 1 | [WindowsAppSDK-Samples](https://github.com/microsoft/WindowsAppSDK-Samples) | All WinAppSDK features (AI, windowing, lifecycle, notifications, etc.) |
| 2 | [AI Dev Gallery](https://github.com/microsoft/ai-dev-gallery) | On-device AI/ML patterns, model usage examples |
| 3 | [WinUI-Gallery](https://github.com/microsoft/WinUI-Gallery) | UI control patterns and XAML examples |
### How to apply
1. **Find the right API** -- Translate the user's scenario/requirement into common API/programming keywords, then search the API references (Part A-B below) using those keywords to identify which API fits.
2. **Search for samples** -- Once you know which API to use, search each sample repo above for the class name to find a working example.
3. **Study the sample** -- Read the sample's Model / ViewModel / Service layer to understand how the API is actually called -- object lifetime, required parameters, data preparation, error handling.
4. **Adapt** the sample pattern into our MVVM architecture -- don't copy the sample structure wholesale, but match its API call sequence exactly.
---
> **Agent Rule:** Before implementing any feature that involves a platform capability, **consult this file** to check whether a built-in API already exists. Always verify exact class names, method signatures, and availability by following the reference links -- do not guess API shapes.
---
## Part A -- Windows App SDK APIs
**Full API reference:** <https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/>
> **Agent Rule:** Do not rely on a hardcoded namespace list -- the SDK is updated frequently. Instead, **search** the API reference above by converting the user's scenario into common programming keywords.
### How to search
1. **Translate** the user's request into API/programming terms. Examples:
- "I want to describe an image" -> search for: `image description`, `ImageDescription`, `describe image`
- "Add a notification" -> search for: `notification`, `toast`, `AppNotification`
- "Pick a file" -> search for: `file picker`, `StoragePicker`, `FileOpenPicker`
- "Make the window always on top" -> search for: `AppWindow`, `presenter`, `compact overlay`
2. **Search** the [WinAppSDK API reference](https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/) using `web_search` or `web_fetch` with those keywords.
3. **Verify** the class/method exists in the SDK version used by this project (check `.csproj` `<PackageReference>` for `Microsoft.WindowsAppSDK` version).
### Key reference links
| # | Link | When to consult |
|---|---|---|
| 1 | [WinAppSDK API Reference (full)](https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/) | **Always** -- search and look up exact class/method signatures here |
| 2 | [Windows App SDK overview](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/) | Feature overview, architecture |
| 3 | [Release notes (stable)](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/stable-channel) | API availability, version support, breaking changes |
| 4 | [Windows AI overview](https://learn.microsoft.com/en-us/windows/ai/) | All AI options: Windows AI APIs, Windows ML, Foundry Local |
| 5 | [Get started with Windows AI APIs](https://learn.microsoft.com/en-us/windows/ai/apis/get-started) | Prerequisites, project setup, first AI call |
| 6 | [Windows ML overview](https://learn.microsoft.com/en-us/windows/ai/new-windows-ml/overview) | Custom ONNX model inference |
| 7 | [Foundry Local](https://learn.microsoft.com/en-us/windows/ai/foundry-local/get-started) | Run OSS LLMs locally |
---
## Part B -- Windows Platform SDK (UWP / WinRT APIs)
**Full API reference:** <https://learn.microsoft.com/en-us/uwp/api/>
> **Agent Rule:** The Platform SDK (`Windows.*` namespaces) is very large and constantly evolving. Do not rely on a hardcoded list. **Search** the API reference by translating the user's requirement into programming keywords.
### How to search
1. **Translate** the user's request into API/programming terms. Examples:
- "Send a Bluetooth message" -> search for: `Bluetooth`, `RFCOMM`, `BluetoothDevice`
- "Get the user's location" -> search for: `geolocation`, `Geolocator`, `position`
- "Read text from an image" -> search for: `OCR`, `text recognition`, `OcrEngine`
- "Copy to clipboard" -> search for: `clipboard`, `DataTransfer`, `DataPackage`
2. **Search** the [Platform SDK API reference](https://learn.microsoft.com/en-us/uwp/api/) using `web_search` or `web_fetch` with those keywords.
3. **Check for WinAppSDK equivalent** -- some Platform SDK APIs have newer equivalents in Part A. Always prefer the WinAppSDK version when both exist.
### Key reference links
| # | Link | When to consult |
|---|---|---|
| 1 | [Platform SDK API Reference (full)](https://learn.microsoft.com/en-us/uwp/api/) | **Search here** for any Windows capability not in WinAppSDK |
| 2 | [Windows SDK downloads](https://developer.microsoft.com/windows/downloads/windows-sdk/) | SDK versions and downloads |
---
## Validation
- Before implementing any platform feature, confirm the API is available in the current Windows App SDK version by checking the [release notes](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/stable-channel).
- For features requiring specific hardware (NPU), provide a graceful fallback for unsupported devices.
- When both WinAppSDK and Platform SDK offer a similar API, prefer the WinAppSDK version.
@@ -0,0 +1,420 @@
---
description: 'WinUI 3 / WinAppSDK architecture, MVVM, XAML patterns, DI, theming, and controls guidance'
applyTo: '**/*.cs, **/*.xaml, **/*.csproj'
---
# WinUI 3 / WinAppSDK -- Best Practices & Patterns
This file covers WinUI 3-specific patterns, conventions, and architecture guidance for this project.
---
## 1. Architecture -- MVVM Pattern
### Overview
Use **Model-View-ViewModel (MVVM)** for all UI features:
| Layer | Responsibility | Example |
|---|---|---|
| **Model** | Data structures & business entities | `Item.cs`, `UserProfile.cs` |
| **View** | XAML UI -- layout, styles, animations | `MainPage.xaml` |
| **ViewModel** | UI state, commands, data transformation | `MainViewModel.cs` |
| **Service** | Business logic, data access, navigation | `IDataService.cs`, `NavigationService.cs` |
### Project Folder Structure
```
<ProjectName>/
Models/ -> Data classes
ViewModels/ -> ViewModels (one per page/dialog)
Views/ -> XAML pages and windows
Services/ -> Business logic & platform services
Converters/ -> IValueConverter implementations
Helpers/ -> Static utility methods
Controls/ -> Custom/reusable controls
Strings/
en-us/
Resources.resw
Assets/ -> Images, icons, splash screens
```
### ViewModel Base
Use `CommunityToolkit.Mvvm` (recommended) for boilerplate-free ViewModels:
```xml
<!-- Use latest stable version; do not hard-code version numbers in instructions -->
<PackageReference Include="CommunityToolkit.Mvvm" Version="*" />
```
```csharp
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
public partial class MainViewModel : ObservableObject
{
[ObservableProperty]
private string _title = string.Empty;
[ObservableProperty]
private bool _isLoading;
[RelayCommand]
private async Task LoadDataAsync()
{
IsLoading = true;
try
{
// Load data
}
finally
{
IsLoading = false;
}
}
}
```
### View-ViewModel Binding
```xml
<Page
x:Class="<RootNamespace>.Views.MainPage"
xmlns:vm="using:<RootNamespace>.ViewModels">
<Page.DataContext>
<vm:MainViewModel />
</Page.DataContext>
<Grid>
<TextBlock Text="{x:Bind ViewModel.Title, Mode=OneWay}" />
<Button Command="{x:Bind ViewModel.LoadDataCommand}" Content="Load" />
</Grid>
</Page>
```
---
## 2. XAML Best Practices
### Use `x:Bind` Over `{Binding}`
| Feature | `x:Bind` | `{Binding}` |
|---|---|---|
| Compile-time check | Yes | No |
| Performance | Faster (compiled) | Slower (reflection) |
| Default mode | OneTime | OneWay |
| IntelliSense | Yes | No |
```xml
<!-- GOOD -->
<TextBlock Text="{x:Bind ViewModel.Name, Mode=OneWay}" />
<!-- AVOID -->
<TextBlock Text="{Binding Name}" />
```
### Use `x:Load` for Deferred Loading
```xml
<StackPanel x:Load="{x:Bind ViewModel.ShowAdvancedOptions, Mode=OneWay}">
<!-- Heavy content loaded only when needed -->
</StackPanel>
```
### Use WinUI Controls from the SDK
Prefer the WinUI 3 controls from `Microsoft.UI.Xaml.Controls`, **not** the older UWP `Windows.UI.Xaml.Controls`:
```csharp
// GOOD -- WinUI 3
using Microsoft.UI.Xaml.Controls;
// AVOID -- UWP (won't work in WinUI 3 desktop)
// using Windows.UI.Xaml.Controls;
```
### XAML Formatting Convention
```xml
<Button
x:Name="SaveButton"
x:Uid="SaveButton"
AutomationProperties.Name="Save"
Command="{x:Bind ViewModel.SaveCommand}"
Style="{StaticResource AccentButtonStyle}" />
```
- One attribute per line for controls with 3+ attributes.
- Order: `x:Name` -> `x:Uid` -> `AutomationProperties` -> layout -> data -> style.
---
## 3. Dependency Injection
### Setup with `Microsoft.Extensions.DependencyInjection`
```xml
<!-- Use latest stable version; do not hard-code version numbers in instructions -->
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="*" />
```
```csharp
// App.xaml.cs
public partial class App : Application
{
public static IServiceProvider Services { get; private set; } = null!;
public App()
{
InitializeComponent();
Services = ConfigureServices();
}
private static IServiceProvider ConfigureServices()
{
var services = new ServiceCollection();
// Services
services.AddSingleton<INavigationService, NavigationService>();
services.AddTransient<IDataService, DataService>();
// ViewModels
services.AddTransient<MainViewModel>();
return services.BuildServiceProvider();
}
}
```
---
## 4. Navigation
### Frame-based Navigation
```csharp
public interface INavigationService
{
bool CanGoBack { get; }
void NavigateTo<TPage>() where TPage : Page;
void GoBack();
}
```
Use a `NavigationView` with a `Frame`:
```xml
<NavigationView SelectionChanged="OnNavigationChanged">
<NavigationView.MenuItems>
<NavigationViewItem Content="Home" Tag="Home" />
<NavigationViewItem Content="Settings" Tag="Settings" />
</NavigationView.MenuItems>
<Frame x:Name="ContentFrame" />
</NavigationView>
```
---
## 5. Windowing & Title Bar
### Custom Title Bar
```csharp
// In Window constructor or Activated handler
ExtendsContentIntoTitleBar = true;
SetTitleBar(AppTitleBar); // AppTitleBar is a UIElement in your XAML
```
```xml
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48" /> <!-- Title bar -->
<RowDefinition Height="*" /> <!-- Content -->
</Grid.RowDefinitions>
<Grid x:Name="AppTitleBar" Grid.Row="0">
<TextBlock Text="My App" VerticalAlignment="Center" Margin="16,0" />
</Grid>
<Frame Grid.Row="1" x:Name="ContentFrame" />
</Grid>
```
### Window Sizing
```csharp
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
var windowId = Win32Interop.GetWindowIdFromWindow(hwnd);
var appWindow = AppWindow.GetFromWindowId(windowId);
appWindow.Resize(new SizeInt32(1280, 720));
```
---
## 6. Theming
### Support Light/Dark/High Contrast
```xml
<!-- In App.xaml -->
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
```
### Detect Theme Changes
```csharp
if (Content is FrameworkElement rootElement)
{
rootElement.ActualThemeChanged += (s, e) =>
{
// React to theme change
};
}
```
### Use Theme Resources, Not Hard-coded Colors
```xml
<!-- GOOD -->
<TextBlock Foreground="{ThemeResource TextFillColorPrimaryBrush}" />
<!-- AVOID -->
<TextBlock Foreground="#000000" />
```
---
## 7. System Backdrop (Mica / Acrylic)
This project uses **Mica** backdrop (already configured in `MainWindow.xaml`):
```xml
<Window.SystemBackdrop>
<MicaBackdrop />
</Window.SystemBackdrop>
```
Alternatives:
```xml
<DesktopAcrylicBackdrop /> <!-- Acrylic -->
<MicaBackdrop Kind="BaseAlt" /> <!-- Mica Alt -->
```
---
## 8. Community Toolkit
### Recommended Packages
```xml
<!-- Use latest stable versions; do not hard-code version numbers in instructions -->
<PackageReference Include="CommunityToolkit.Mvvm" Version="*" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="*" />
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="*" />
<PackageReference Include="CommunityToolkit.WinUI.Animations" Version="*" />
```
### Useful Toolkit Features
| Feature | Package | Use Case |
|---|---|---|
| `ObservableObject` | CommunityToolkit.Mvvm | ViewModel base class |
| `RelayCommand` | CommunityToolkit.Mvvm | Command implementation |
| `ObservableProperty` | CommunityToolkit.Mvvm | Auto INotifyPropertyChanged |
| `SettingsCard` | CommunityToolkit.WinUI.Controls | Settings pages |
| `IncrementalLoadingCollection` | CommunityToolkit.WinUI | Lazy-loading lists |
---
## 9. Common Pitfalls
| Pitfall | Solution |
|---|---|
| Using `Windows.UI.Xaml` namespace | Use `Microsoft.UI.Xaml` for WinUI 3 |
| Calling `Window.Current` | Not available in WinUI 3 -- pass window reference explicitly |
| Using `CoreDispatcher` | Use `DispatcherQueue` instead |
| `REGDB_E_CLASSNOTREG` error | Ensure Developer Mode is enabled, then re-register: run `winapp unregister` followed by `dotnet run` (or `winapp run <build-output>`) to refresh the loose-layout registration |
| Stale package state after manifest changes | Run `winapp unregister`, then `dotnet run` -- using `winapp run --clean` additionally wipes `LocalState`/settings to test first-run behavior |
| XAML Designer crashes | Clean & rebuild; ensure platform matches (x64 vs AnyCPU) |
| `{Binding}` not updating | Switch to `x:Bind` with `Mode=OneWay` or `Mode=TwoWay` |
---
## 10. Validation
Build & register the MSIX package -- see **Build, Run & Deploy** in `.github/agents/Agents.md`.
### Verify
- Run the app and verify the changed UI renders correctly on x64.
- Search XAML for `{Binding` -- replace with `x:Bind`.
- Search XAML for `Foreground="#` or `Background="#` -- replace with `{ThemeResource}`.
- Search C# for `Windows.UI.Xaml` -- replace with `Microsoft.UI.Xaml`.
- Search C# for `Window.Current` -- replace with explicit window reference.
- Search C# for `CoreDispatcher` -- replace with `DispatcherQueue`.
- Test Light, Dark, and High Contrast themes.
---
## 11. Must Read & Research
> **Agent Rule:** Before making any WinUI/WinAppSDK-related change, you **must** fetch and review the relevant references below using `fetch_webpage`. Consult the appropriate section based on the type of change. Apply what you learn -- do not skip this step.
### Official Documentation
| # | Reference | When to consult |
|---|---|---|
| 1 | [WinUI 3 Overview](https://learn.microsoft.com/en-us/windows/apps/winui/winui3/) | Starting new features, onboarding to the project |
| 2 | [Windows App SDK](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/) | Using SDK-specific APIs (windowing, lifecycle, activation) |
| 3 | [WinUI 3 API Reference](https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/) | Looking up specific class/method signatures |
| 4 | [WinUI 3 Gallery App](https://learn.microsoft.com/en-us/windows/apps/design/controls/) | Choosing controls, reviewing control patterns |
| 5 | [AI Dev Gallery](https://github.com/microsoft/ai-dev-gallery) | On-device AI/ML integration patterns, model usage examples in WinUI |
| 6 | [Windows App SDK Release Notes](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/stable-channel) | Checking for breaking changes, new APIs, known issues |
### Architecture & Patterns
| # | Reference | When to consult |
|---|---|---|
| 7 | [CommunityToolkit.Mvvm Docs](https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/) | Implementing ViewModels, commands, `ObservableProperty` |
| 8 | [Dependency Injection in .NET](https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection) | Registering services, constructor injection, lifetime management |
| 9 | [Template Studio for WinUI](https://github.com/microsoft/TemplateStudio) | Scaffolding pages, navigation, project structure patterns |
### Controls & Design
| # | Reference | When to consult |
|---|---|---|
| 10 | [WinUI 3 Gallery (GitHub)](https://github.com/microsoft/WinUI-Gallery) | Example implementations of any WinUI control |
| 11 | [Windows Community Toolkit (GitHub)](https://github.com/CommunityToolkit/Windows) | Before building custom controls -- check if the toolkit already has one |
| 12 | [Fluent Design System](https://learn.microsoft.com/en-us/windows/apps/design/) | Spacing, typography, colour, motion, layout decisions |
| 13 | [XAML Controls Gallery](https://apps.microsoft.com/store/detail/winui-3-gallery/9P3JFPWWDZRC) | Interactive demo of all controls and their properties |
### Windows APIs & AI
| # | Reference | When to consult |
|---|---|---|
| 14 | [Windows APIs instruction file](windows-apis.instructions.md) | **First stop** -- check if a built-in API already exists for the capability you need (AI, windowing, notifications, widgets, lifecycle, etc.) |
| 15 | [Windows AI APIs](https://learn.microsoft.com/en-us/windows/ai/apis/) | On-device AI: Phi Silica (text gen), OCR, imaging (super-res, description, object extract, erase) |
| 16 | [Windows ML](https://learn.microsoft.com/en-us/windows/ai/new-windows-ml/overview) | Custom ONNX model inference on CPU/GPU/NPU |
| 17 | [Foundry Local](https://learn.microsoft.com/en-us/windows/ai/foundry-local/get-started) | Run OSS LLMs (Llama, Mistral, Phi) locally via REST API |
| 18 | [Windows AI on Windows](https://learn.microsoft.com/en-us/windows/ai/) | AI landing page -- all AI options for Windows apps |
### Samples
> **Agent Rule -- MANDATORY:** Before implementing any WinAppSDK or Platform SDK API you have not used before, **search the samples repo first** and study the working example. Do not guess API usage from docs alone -- see the [Sample-First Rule](windows-apis.instructions.md#sample-first-rule) for details and known pitfalls.
| # | Reference | When to consult |
|---|---|---|
| 19 | [Windows App SDK Samples](https://github.com/microsoft/WindowsAppSDK-Samples) | **Always search here first** before implementing any SDK API for the first time |
| 20 | [WinUI 3 Demos](https://github.com/microsoft/WinUI-Gallery) | Reference implementations and patterns |
| 21 | [Windows AI API Samples](https://github.com/microsoft/WindowsAppSDK-Samples/tree/main/Samples/WindowsAIFoundry/cs-winui) | AI API usage with WinUI (ImageDescription, TextRecognizer, LanguageModel, etc.) |