Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
WinUI 3 / Windows App SDK development: project setup with UseWinUI and Windows 10 TFM, XAML patterns with compiled
bindings (x:Bind) and deferred loading (x:Load), MVVM with CommunityToolkit.Mvvm, MSIX and unpackaged deployment
modes, Windows integration (lifecycle, notifications, widgets), UWP migration guidance, and common agent pitfalls.
Version assumptions: .NET 8.0+ baseline. Windows App SDK 1.6+ (current stable). TFM net8.0-windows10.0.19041.0.
.NET 9 features explicitly marked.
Windows integration (lifecycle, notifications, widgets)
UWP migration guidance
Out of scope
Desktop UI testing (Appium, WinAppDriver) -- see [skill:dotnet-ui-testing-core]
General Native AOT patterns -- see [skill:dotnet-native-aot]
UI framework selection decision tree -- see [skill:dotnet-ui-chooser]
WPF patterns -- see [skill:dotnet-wpf-modern]
Cross-references: [skill:dotnet-ui-testing-core] for desktop testing, [skill:dotnet-wpf-modern] for WPF patterns,
[skill:dotnet-wpf-migration] for migration guidance, [skill:dotnet-native-aot] for general AOT,
[skill:dotnet-ui-chooser] for framework selection, [skill:dotnet-native-interop] for general P/Invoke patterns (CsWin32
generates P/Invoke declarations), [skill:dotnet-accessibility] for accessibility patterns (AutomationProperties,
AutomationPeer, UI Automation).
Project Setup
WinUI 3 uses the Windows App SDK (formerly Project Reunion) as its runtime and API layer. Projects target a Windows 10
version-specific TFM.
<!-- MyWinUIApp.csproj --><ProjectSdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>WinExe</OutputType><TargetFramework>net8.0-windows10.0.19041.0</TargetFramework><UseWinUI>true
enable
enable
true
```text
### Project Layout
```text
MyWinUIApp/
App.xaml / App.xaml.cs # Application entry, resource dictionaries
MainWindow.xaml / .xaml.cs # Main window
ViewModels/ # MVVM ViewModels
Views/ # XAML pages (for Frame navigation)
Models/ # Data models
Services/ # Service interfaces and implementations
Assets/ # Images, icons
Package.appxmanifest # MSIX manifest (packaged mode)
Properties/
launchSettings.json
```json
### Host Builder Pattern
Modern WinUI apps use the generic host for dependency injection and service configuration:
```csharp
// App.xaml.cs
public partial class App : Application
{
private readonly IHost _host;
public App()
{
this.InitializeComponent();
_host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
// Services
services.AddSingleton<INavigationService, NavigationService>();
services.AddSingleton<IProductService, ProductService>();
// ViewModels
services.AddTransient();
services.AddTransient();
// Views
services.AddTransient();
services.AddTransient();
// Windows
services.AddSingleton();
})
.Build();
}
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
await _host.StartAsync();
var mainWindow = _host.Services.GetRequiredService();
mainWindow.Closed += async (_, _) =>
{
await _host.StopAsync();
_host.Dispose();
};
mainWindow.Activate();
}
public static T GetService() where T : class
{
var app = (App)Application.Current;
return app._host.Services.GetRequiredService();
}
}
```text
### TFM Requirements
The `net8.0-windows10.0.19041.0` TFM specifies:
- **.NET 8.0** -- the runtime version
- **Windows 10 build 19041** (version 2004) -- the minimum Windows SDK version
Windows App SDK features may require higher SDK versions:
- **Widgets (Windows 11):** `net8.0-windows10.0.22000.0` (Windows 11 build 22000)
- **Mica backdrop:** `net8.0-windows10.0.22000.0`
- **Snap layouts integration:** `net8.0-windows10.0.22000.0`
---
## XAML Patterns
WinUI 3 XAML is distinct from UWP XAML. The root namespace is `Microsoft.UI.Xaml`, not `Windows.UI.Xaml`.
### Compiled Bindings (x:Bind)
`x:Bind` provides compile-time type checking and better performance than `{Binding}`. It resolves properties relative to the code-behind class (not the `DataContext`).
```xml
```text
```csharp
// Code-behind: expose ViewModel property for x:Bind
public sealed partial class ProductListPage : Page
{
public ProductListViewModel ViewModel { get; }
public ProductListPage()
{
ViewModel = App.GetService();
this.InitializeComponent();
}
}
```text
**Key differences from `{Binding}`:**
- `x:Bind` is resolved at compile time (type-safe, faster)
- Default mode is `OneTime` (not `OneWay` like `{Binding}`)
- Resolves against the code-behind class, not `DataContext`
- Requires `x:DataType` in `DataTemplate` items
### Deferred Loading (x:Load)
Use `x:Load` to defer element creation until needed, reducing initial page load time:
```xml
```text
**When to use `x:Load`:** Heavy UI sections (complex lists, settings panels, detail views) that are not immediately visible. The element is created when the bound property becomes `true` and destroyed when it becomes `false`.
### NavigationView Pattern
WinUI apps typically use `NavigationView` with a `Frame` for page navigation:
```xml
```text
---
## MVVM
WinUI 3 integrates with CommunityToolkit.Mvvm (the same MVVM Toolkit used by MAUI). Source generators eliminate boilerplate for properties and commands.
```csharp
// ViewModels/ProductListViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
public partial class ProductListViewModel : ObservableObject
{
private readonly IProductService _productService;
public ProductListViewModel(IProductService productService)
{
_productService = productService;
}
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(SearchCommand))]
private string _searchTerm = "";
[ObservableProperty]
private ObservableCollection _products = [];
[ObservableProperty]
private bool _isLoading;
[ObservableProperty]
private bool _showDetails;
[RelayCommand]
private async Task LoadProductsAsync(CancellationToken ct)
{
IsLoading = true;
try
{
var items = await _productService.GetProductsAsync(ct);
Products = new ObservableCollection(
items.Select(p => new ProductViewModel(p)));
}
finally
{
IsLoading = false;
}
}
[RelayCommand(CanExecute = nameof(CanSearch))]
private async Task SearchAsync(CancellationToken ct)
{
var results = await _productService.SearchAsync(SearchTerm, ct);
Products = new ObservableCollection(
results.Select(p => new ProductViewModel(p)));
}
private bool CanSearch() => !string.IsNullOrWhiteSpace(SearchTerm);
}
```text
**Key source generator attributes:**
- `[ObservableProperty]` -- generates property with `INotifyPropertyChanged` from a backing field
- `[RelayCommand]` -- generates `ICommand` from a method (supports async, cancellation, `CanExecute`)
- `[NotifyPropertyChangedFor]` -- raises `PropertyChanged` for dependent properties
- `[NotifyCanExecuteChangedFor]` -- re-evaluates command `CanExecute` when property changes
---
## Packaging
WinUI 3 supports two deployment models: MSIX packaged and unpackaged. The choice affects app identity, capabilities, and distribution.
### MSIX Packaged Deployment
MSIX is the default packaging model. It provides app identity, clean install/uninstall, automatic updates, and access to full Windows integration APIs.
```xml
```text
```bash
# Build MSIX package
dotnet publish -c Release -r win-x64
```bash
### Unpackaged Deployment
Unpackaged mode removes MSIX requirements. The app runs as a standard Win32 executable without app identity.
```xml
None
```csharp
**Trade-offs:**
| Feature | MSIX Packaged | Unpackaged |
|---------|--------------|------------|
| App identity | Yes | No |
| Clean install/uninstall | Yes (Add/Remove Programs) | Manual |
| Auto-update | Yes (Store, App Installer) | Manual |
| Background tasks | Full support | Limited |
| Toast notifications | Full support | Requires COM registration |
| Widgets (Windows 11) | Yes | No |
| File type associations | Via manifest | Via registry |
| Distribution | Store, sideload, App Installer | xcopy, installer (MSI/EXE) |
| Startup time | Slightly slower (package verification) | Faster |
**When to choose unpackaged:**
- Internal enterprise tools with existing deployment infrastructure
- Apps that need xcopy deployment or integration with existing MSI/EXE installers
- Quick prototypes where packaging overhead is unnecessary
- Apps that do not need Windows identity features
---
## Windows Integration
### App Lifecycle
WinUI 3 apps use the Windows App SDK activation and lifecycle model, distinct from UWP's `CoreApplication`.
```csharp
// Handle activation kinds (protocol, file, toast, etc.)
public partial class App : Application
{
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
// Check for specific activation
var activationArgs = AppInstance.GetCurrent().GetActivatedEventArgs();
switch (activationArgs.Kind)
{
case ExtendedActivationKind.Protocol:
var protocolArgs = (ProtocolActivatedEventArgs)activationArgs.Data;
HandleProtocolActivation(protocolArgs.Uri);
break;
case ExtendedActivationKind.File:
var fileArgs = (FileActivatedEventArgs)activationArgs.Data;
HandleFileActivation(fileArgs.Files);
break;
default:
// Normal launch
break;
}
}
}
```text
### Notifications
Toast notifications require the Windows App SDK notification APIs:
```csharp
using Microsoft.Windows.AppNotifications;
using Microsoft.Windows.AppNotifications.Builder;
// Register for notification activation
var notificationManager = AppNotificationManager.Default;
notificationManager.NotificationInvoked += OnNotificationInvoked;
notificationManager.Register();
// Send a toast notification
var builder = new AppNotificationBuilder()
.AddText("Order Shipped")
.AddText("Your order #12345 has shipped.")
.AddButton(new AppNotificationButton("Track")
.AddArgument("action", "track")
.AddArgument("orderId", "12345"));
AppNotificationManager.Default.Show(builder.BuildNotification());
```text
### Widgets (Windows 11)
Widgets require Windows 11 (build 22000+) and MSIX packaged deployment. The implementation involves creating a widget provider that implements `IWidgetProvider` and registering it in the MSIX manifest.
**Key steps:**
1. Implement `IWidgetProvider` interface (methods: `CreateWidget`, `DeleteWidget`, `OnActionInvoked`, `OnWidgetContextChanged`, `OnCustomizationRequested`, `Activate`, `Deactivate`)
2. Register the provider as a COM class in the MSIX manifest
3. Define widget templates using Adaptive Cards JSON format
4. Return updated widget content from provider methods
See the [Windows App SDK Widget documentation](https://learn.microsoft.com/en-us/windows/apps/develop/widgets/widget-providers) for the complete interface contract and manifest registration.
### Taskbar Integration
Taskbar progress in WinUI 3 requires Win32 COM interop via the `ITaskbarList3` interface. Unlike UWP which had a managed `TaskbarManager`, WinUI 3 does not expose a managed wrapper.
```csharp
// Taskbar progress requires COM interop in WinUI 3
// Use CsWin32 source generator or manual P/Invoke for ITaskbarList3
// 1. Add CsWin32:
// 2. Add to NativeMethods.txt: ITaskbarList3
// See: https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-itaskbarlist3
```csharp
---
## UWP Migration
Migrating from UWP to WinUI 3 involves namespace changes, API replacements, and project restructuring.
### Namespace Changes
| UWP Namespace | WinUI 3 Namespace |
|---------------|-------------------|
| `Windows.UI.Xaml` | `Microsoft.UI.Xaml` |
| `Windows.UI.Xaml.Controls` | `Microsoft.UI.Xaml.Controls` |
| `Windows.UI.Xaml.Media` | `Microsoft.UI.Xaml.Media` |
| `Windows.UI.Xaml.Input` | `Microsoft.UI.Xaml.Input` |
| `Windows.UI.Composition` | `Microsoft.UI.Composition` |
| `Windows.UI.Text` | `Microsoft.UI.Text` |
| `Windows.UI.Colors` | `Microsoft.UI.Colors` |
**Keep as-is:** `Windows.Storage`, `Windows.Networking`, `Windows.Security`, `Windows.ApplicationModel`, `Windows.Devices` -- these WinRT APIs remain in the `Windows.*` namespace.
### API Replacements
| UWP API | WinUI 3 Replacement |
|---------|---------------------|
| `CoreApplication.MainView` | `App.MainWindow` (track your own window reference) |
| `CoreDispatcher.RunAsync` | `DispatcherQueue.TryEnqueue` |
| `Window.Current` | Track window reference manually in App class |
| `ApplicationView.Title` | `window.Title = "..."` |
| `CoreWindow.GetForCurrentThread` | Not available; use `InputKeyboardSource` for keyboard APIs |
| `SystemNavigationManager.BackRequested` | `NavigationView.BackRequested` |
### Migration Steps
1. **Create a new WinUI 3 project** using the Windows App SDK template
2. **Copy source files** and update namespaces (`Windows.UI.Xaml` to `Microsoft.UI.Xaml`)
3. **Update XAML namespaces** in all `.xaml` files
4. **Replace deprecated APIs** (see table above)
5. **Migrate packaging** from `.appxmanifest` UWP format to Windows App SDK format
6. **Update NuGet packages** to Windows App SDK-compatible versions
7. **Test Windows integration** features (notifications, background tasks, file associations)
For comprehensive migration path guidance across frameworks, see [skill:dotnet-wpf-migration].
**UWP .NET 9 preview path:** Microsoft announced UWP support on .NET 9 as a preview. This allows UWP apps to use modern .NET without migrating to WinUI 3. Evaluate this path if full WinUI migration is too costly but you need modern .NET runtime features.
---
## Agent Gotchas
1. **Do not confuse UWP XAML with WinUI 3 XAML.** The root namespace changed from `Windows.UI.Xaml` to `Microsoft.UI.Xaml`. Code using `Windows.UI.Xaml.*` types will not compile in WinUI 3 projects.
2. **Do not use `Window.Current`.** WinUI 3 does not have a static `Window.Current` property. Track your window reference manually in the `App` class and pass it via DI or a static property.
3. **Do not use `CoreDispatcher`.** Replace `CoreDispatcher.RunAsync()` with `DispatcherQueue.TryEnqueue()`. `CoreDispatcher` is a UWP API not available in WinUI 3.
4. **Do not assume MSIX is required.** WinUI 3 supports unpackaged deployment via `None`. Only use MSIX when you need app identity, Store distribution, or Windows integration features that require it.
5. **Do not forget `x:Bind` defaults to `OneTime`.** Unlike `{Binding}` which defaults to `OneWay`, `x:Bind` defaults to `OneTime`. Always specify `Mode=OneWay` or `Mode=TwoWay` for properties that change after initial binding.
6. **Do not target Windows 10 builds below 19041.** Windows App SDK 1.6+ requires a minimum of build 19041 (version 2004). Targeting lower builds causes runtime failures.
7. **Do not use Widgets or Mica in unpackaged apps.** These features require MSIX packaged deployment with app identity. Attempting to use them in unpackaged mode fails silently or throws.
8. **Do not mix CommunityToolkit.Mvvm with manual INotifyPropertyChanged.** Use `[ObservableProperty]` consistently. Mixing source-generated and hand-written implementations causes subtle binding bugs.
9. **Do not forget the Host builder lifecycle.** Call `_host.StartAsync()` in `OnLaunched` and `_host.StopAsync()` when the window closes. Forgetting lifecycle management causes DI-registered `IHostedService` instances to never start or stop.
---
## Prerequisites
- .NET 8.0+ with Windows desktop workload
- Windows App SDK 1.6+ (auto-referenced via `UseWinUI`)
- Windows 10 version 2004 (build 19041) or later
- Visual Studio 2022+ with Windows App SDK workload, or VS Code with C# Dev Kit
- For widgets: Windows 11 (build 22000+)
---
## References
- [WinUI 3 Documentation](https://learn.microsoft.com/en-us/windows/apps/winui/winui3/)
- [Windows App SDK](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/)
- [CommunityToolkit.Mvvm](https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/)
- [UWP to WinUI Migration](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/migrate-to-windows-app-sdk/)
- [MSIX Packaging](https://learn.microsoft.com/en-us/windows/msix/)
- [Windows App SDK Deployment Guide](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/deploy-overview)
</UseWinUI>
<Nullable>
</Nullable>
<ImplicitUsings>
</ImplicitUsings>
<!-- Windows App SDK version (auto-referenced via UseWinUI) -->