Skip to content

Commit c92be24

Browse files
committed
Merge branch 'main' into niels9001/widgets
2 parents c2fd468 + f3be5c1 commit c92be24

6 files changed

Lines changed: 102 additions & 5 deletions

File tree

hub/apps/develop/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,8 @@ items:
10381038
items:
10391039
- name: Integrate Windows App SDK
10401040
href: ../windows-app-sdk/migrate-to-windows-app-sdk/wpf-plus-winappsdk.md
1041+
- name: Migrate WPF patterns to WinUI 3
1042+
href: ../windows-app-sdk/migrate-to-windows-app-sdk/wpf-patterns-winui3.md
10411043
- name: Visual layer
10421044
items:
10431045
- name: Overview

hub/apps/tutorials/winui-notes/all-notes.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ The new data model represents the data required to display multiple notes. Here,
8989

9090
The previous code declares a collection of `Note` items, named `Notes`, and uses the `LoadNotes` method to load notes from the app's local storage.
9191

92+
> [!NOTE]
93+
> The `LoadNotes` method uses `async void` instead of `async Task` because it's called from the constructor, which cannot be `async`. This fire-and-forget pattern is acceptable here since the method is an event-like initialization routine.
94+
9295
The `Notes` collection uses an [ObservableCollection](/dotnet/api/system.collections.objectmodel.observablecollection-1), which is a specialized collection that works well with data binding. When a control that lists multiple items, such as an [ItemsView](../../design/controls/itemsview.md), is bound to an `ObservableCollection`, the two work together to automatically keep the list of items in sync with the collection. If an item is added to the collection, the control is automatically updated with the new item. If an item is added to the list, the collection is updated.
9396

9497
:::image type="icon" source="media/doc-icon-sm.png" border="false"::: Learn more in the docs:
@@ -101,6 +104,9 @@ Now that the `AllNotes` model is ready to provide data for the view, you need to
101104
1. In the **Solution Explorer** pane, open the **Views\AllNotesPage.xaml.cs** file.
102105
1. In the `AllNotesPage` class, add this code to create an `AllNotes` model named _notesModel_:
103106

107+
> [!NOTE]
108+
> You'll need to add `using WinUINotes.Models;` at the top of the file to reference the `AllNotes` class.
109+
104110
```csharp
105111
public sealed partial class AllNotesPage : Page
106112
{
@@ -170,7 +176,7 @@ If you run the app now, you'll see that the note you created previously is loade
170176

171177
### Add a data template
172178

173-
You need to specify a [DataTemplate](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.datatemplate) to tell the `ItemsView` how your data item should be shown. The `DataTemplate` is assigned to the [ItemsTemplate](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.itemsview.itemtemplate) property of the `ItemsView`. For each item in the collection, the `ItemsView.ItemTemplate` generates the declared XAML.
179+
You need to specify a [DataTemplate](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.datatemplate) to tell the `ItemsView` how your data item should be shown. The `DataTemplate` is assigned to the [ItemTemplate](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.itemsview.itemtemplate) property of the `ItemsView`. For each item in the collection, the `ItemsView.ItemTemplate` generates the declared XAML.
174180

175181
1. In the **Solution Explorer** pane, double-click on the **AllNotesPage.xaml** entry to open it in the XAML editor.
176182
1. Add this new namespace mapping on the line below the mapping for `local`:
@@ -219,7 +225,7 @@ You need to specify a [DataTemplate](/windows/windows-app-sdk/api/winrt/microsof
219225
</Page.Resources>
220226
```
221227

222-
1. In the XAML for `ItemsView`, assign the `ItemTemplate` property to the data template you just created:
228+
1. In the XAML for `ItemsView`, change `Padding="16"` to `Margin="24"` and assign the `ItemTemplate` property to the data template you just created:
223229

224230
```xaml
225231
<ItemsView ItemsSource="{x:Bind notesModel.Notes}"

hub/apps/tutorials/winui-notes/navigation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ On the note page, you'll add a _back_ button, and there are **Save** and **Delet
2424

2525
## New note
2626

27-
First, you'll handle navigation for an new note.
27+
First, you'll handle navigation for a new note.
2828

2929
> [!TIP]
3030
> You can download or view the code for this tutorial from the [GitHub repo](https://github.com/MicrosoftDocs/windows-topic-specific-samples/tree/winui-3/tutorials/winui-notes). To see the code as it is in this step, see this commit: [navigation - new note](https://github.com/MicrosoftDocs/windows-topic-specific-samples/tree/25c23e5976c6b791355b109c7a7a0430ab16a3f9/WinUINotes).

hub/apps/tutorials/winui-notes/note.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ namespace WinUINotes
287287

288288
With this code in place, you can test the app to make sure the note saves and loads correctly.
289289

290-
1. Build and run the project by pressing <kbd>F5</kbd>, clicking the Debug "Start" button in the tool bar, or by selecting the menu **Run** > **Start Debugging**.
290+
1. Build and run the project by pressing <kbd>F5</kbd>, clicking the Debug "Start" button in the tool bar, or by selecting the menu **Debug** > **Start Debugging**.
291291
1. Type into the text entry box and press the **Save** button.
292292
1. Close the app, then restart it. The note you entered should be loaded from the device's storage.
293293
1. Press the **Delete** button.

hub/apps/tutorials/winui-notes/project.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ You need to write a bit of code to finish replacing the system title bar.
153153

154154
The [ExtendsContentIntoTitleBar](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.window.extendscontentintotitlebar) property hides the default system title bar and extends your app XAML into that area. The call to [SetTitleBar](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.window.settitlebar) then tells the system to treat the XAML element you specified (`AppTitleBar`) as the title bar for the app.
155155

156-
1. Build and run the project by pressing <kbd>F5</kbd>, clicking the Debug "Start" button in the tool bar, or by selecting the menu **Run** > **Start Debugging**.
156+
1. Build and run the project by pressing <kbd>F5</kbd>, clicking the Debug "Start" button in the tool bar, or by selecting the menu **Debug** > **Start Debugging**.
157157

158158
When you run the app now, you'll see an empty window with a mica background and the XAML title bar that's replaced the system title bar.
159159

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
title: Migrate WPF app patterns to WinUI 3
3+
description: WinUI 3 shares many XAML concepts with WPF and is optimized for modern Windows experiences. This topic maps common WPF patterns to their WinUI 3 equivalents to help you plan your migration.
4+
ms.topic: concept-article
5+
ms.date: 04/07/2026
6+
keywords: windows, app, sdk, wpf, winui, winui3, migration, patterns, equivalents
7+
ms.localizationpriority: medium
8+
---
9+
10+
# Migrate WPF app patterns to WinUI 3
11+
12+
WinUI 3 shares many XAML concepts with WPF and is optimized for modern Windows experiences. Most WPF patterns have direct equivalents in WinUI 3. In some areas WinUI 3 introduces an improved approach that replaces an older pattern, and in a few cases features are still in active development.
13+
14+
This topic maps common WPF patterns to their WinUI 3 equivalents so you can plan your migration.
15+
16+
> [!TIP]
17+
> For general WPF + Windows App SDK guidance, see [Use the Windows App SDK in a WPF app](wpf-plus-winappsdk.md).
18+
19+
## Controls
20+
21+
Most WPF controls have direct equivalents in WinUI 3. The following table covers controls where the mapping is not one-to-one.
22+
23+
| WPF control | WinUI 3 equivalent | Notes |
24+
|---|---|---|
25+
| [`DataGrid`](/dotnet/api/system.windows.controls.datagrid) | No first-party equivalent | WinUI 3 does not include a built-in DataGrid. The community-maintained [WinUI.TableView](https://github.com/w-ahmad/WinUI.TableView) is one option. Evaluate community projects based on your support and maintenance requirements. |
26+
| [`Ribbon`](/dotnet/api/system.windows.controls.ribbon.ribbon) | `CommandBar` / Community Toolkit Labs | Consider [CommandBar](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.commandbar) and [CommandBarFlyout](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.commandbarflyout) for toolbar-style scenarios. A [Ribbon control](https://github.com/CommunityToolkit/Labs-Windows/tree/main/components/Ribbon) is also available in Community Toolkit Labs (experimental). |
27+
| [`StatusBar`](/dotnet/api/system.windows.controls.primitives.statusbar) | `InfoBar` + custom layout | Use [InfoBar](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.infobar) for status messaging, or add a dedicated footer area to your layout. |
28+
| [`FlowDocumentReader`](/dotnet/api/system.windows.controls.flowdocumentreader) / [`FlowDocumentScrollViewer`](/dotnet/api/system.windows.controls.flowdocumentscrollviewer) | [`RichTextBlock`](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.richtextblock) | Use [RichTextBlock](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.richtextblock) for read-only rich text display. WinUI 3 takes a different approach to document content that is better suited to modern app scenarios. |
29+
| [`PasswordBox`](/dotnet/api/system.windows.controls.passwordbox) with `SecureString` | [`PasswordBox`](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.passwordbox) | WinUI 3's [PasswordBox](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.passwordbox) provides password masking. `SecureString` is deprecated in .NET 5+; the recommended approach is to minimize how long credentials are held in memory using `ReadOnlySpan<char>` patterns. |
30+
| [`WebBrowser`](/dotnet/api/system.windows.controls.webbrowser) | [WebView2](/microsoft-edge/webview2/) | `WebView2` uses the modern Microsoft Edge (Chromium) engine and is the recommended approach for embedding web content across all desktop app types. |
31+
32+
## XAML features
33+
34+
WinUI 3 XAML uses the same core concepts as WPF — resource dictionaries, styles, data binding, and markup extensions all work similarly. Some WPF-specific patterns have evolved into improved, more composable alternatives.
35+
36+
| WPF feature | WinUI 3 approach | Notes |
37+
|---|---|---|
38+
| [`DataTrigger`](/dotnet/api/system.windows.datatrigger) / [`MultiTrigger`](/dotnet/api/system.windows.multitrigger) | [Behaviors (Community Toolkit)](https://aka.ms/toolkit/behaviors) | WinUI 3 uses attached behaviors rather than inline triggers. The XAML Behaviors package supports `DataTriggerBehavior`, `EventTriggerBehavior`, and more. Behaviors are more composable and unit-testable than WPF triggers. |
39+
| [`DynamicResource`](/dotnet/desktop/wpf/advanced/dynamicresource-markup-extension) | [`ThemeResource`](/windows/uwp/xaml-platform/themeresource-markup-extension) | `ThemeResource` provides runtime resource lookup and responds automatically to theme changes (light, dark, high contrast). Use `StaticResource` for values that never change at runtime. |
40+
| [`MultiBinding`](/dotnet/api/system.windows.data.multibinding) / [`PriorityBinding`](/dotnet/api/system.windows.data.prioritybinding) | Converters or `x:Bind` | Use a multi-value converter with individual bindings, or use `x:Bind` with a computed property on your view model. `x:Bind` is compiled and type-safe, which makes it more performant than `Binding`. |
41+
| `Style` with `BasedOn` | ✅ Supported | Style inheritance with `BasedOn` works in WinUI 3. |
42+
| Implicit styles | ✅ Supported | Resource dictionary implicit styles (styles without `x:Key`) work as expected. |
43+
| [`AdornerLayer`](/dotnet/api/system.windows.documents.adornerlayer) | Custom overlay approach | WinUI 3 has no adorner layer equivalent. Use a `Canvas` or `Grid` overlay in your layout to achieve similar visual decoration effects — this approach is more explicit and easier to reason about. |
44+
45+
## Threading and dispatch
46+
47+
| WPF pattern | WinUI 3 equivalent | Notes |
48+
|---|---|---|
49+
| [`Dispatcher.Invoke`](/dotnet/api/system.windows.threading.dispatcher.invoke) / `BeginInvoke` | [`DispatcherQueue.TryEnqueue`](/windows/windows-app-sdk/api/winrt/microsoft.ui.dispatching.dispatcherqueue.tryenqueue) | WinUI 3 uses [DispatcherQueue](/windows/windows-app-sdk/api/winrt/microsoft.ui.dispatching.dispatcherqueue). The async pattern is `await DispatcherQueue.EnqueueAsync(...)` using the Community Toolkit extension. |
50+
| [`Application.Current.Dispatcher`](/dotnet/api/system.windows.application.current) | [`DispatcherQueue.GetForCurrentThread()`](/windows/windows-app-sdk/api/winrt/microsoft.ui.dispatching.dispatcherqueue.getforcurrentthread) | Capture the `DispatcherQueue` at construction time on the UI thread and store it for later use on background threads. |
51+
| [`BackgroundWorker`](/dotnet/api/system.componentmodel.backgroundworker) | `Task` / `async`-`await` | Modern .NET async patterns are the right approach in WinUI 3. `Task`, `CancellationToken`, and `IProgress<T>` cover all `BackgroundWorker` scenarios and integrate naturally with `x:Bind`. |
52+
53+
## App model and lifecycle
54+
55+
| WPF concept | WinUI 3 equivalent | Notes |
56+
|---|---|---|
57+
| `Application.Startup` / `Exit` events | `App.OnLaunched` / `Window.Closed` | WinUI 3 uses `OnLaunched` in `App.xaml.cs` as the entry point. Per-window teardown is handled in `Window.Closed`. |
58+
| `Application.Current.MainWindow` | Your `Window` instance | Hold a reference to your window instance in `App.xaml.cs` and expose it as a property. |
59+
| `Window` subclassing | [AppWindow](/windows/windows-app-sdk/api/winrt/microsoft.ui.windowing.appwindow) customization | WinUI 3 windows are customized through `AppWindow` (title bar, presenter, overlapped/fullscreen/compact overlay modes) rather than subclassing. See [Manage app windows](../../develop/ui/manage-app-windows.md). |
60+
| `SystemParameters` | `DisplayArea` / `UISettings` | System display properties are available through [DisplayArea](/windows/windows-app-sdk/api/winrt/microsoft.ui.windowing.displayarea) and [UISettings](/uwp/api/windows.ui.viewmanagement.uisettings). |
61+
62+
## Resources and localization
63+
64+
| WPF pattern | WinUI 3 equivalent | Notes |
65+
|---|---|---|
66+
| `.resx` resource files | `.resw` + `ResourceLoader` | WinUI 3 uses `.resw` files and the [ResourceLoader](/windows/windows-app-sdk/api/winrt/microsoft.windows.applicationmodel.resources.resourceloader) API. The .NET Upgrade Assistant can automate much of this conversion. |
67+
| `x:Static` markup extension | `x:Bind` to a static property | Use `x:Bind` with a static property or a singleton accessor. `x:Bind` is compiled and produces clearer error messages than `x:Static`. |
68+
| Merged resource dictionaries | ✅ Supported | `ResourceDictionary.MergedDictionaries` works in WinUI 3. |
69+
| Theme-specific resource dictionaries | ✅ Supported | `ResourceDictionary.ThemeDictionaries` is the WinUI 3 mechanism for per-theme resources, and integrates with automatic dark/light mode switching. |
70+
71+
## Printing
72+
73+
| WPF feature | WinUI 3 status | Notes |
74+
|---|---|---|
75+
| [`PrintDialog`](/dotnet/api/system.windows.controls.printdialog) / [`PrintDocument`](/dotnet/api/system.drawing.printing.printdocument) | [PrintManager](/uwp/api/windows.graphics.printing.printmanager) | Full printing support is available via `PrintManager`. See [Print from your app](/windows/apps/develop/devices-sensors/print-from-your-app). |
76+
77+
## Developer tooling
78+
79+
| WPF tooling | WinUI 3 status | Notes |
80+
|---|---|---|
81+
| XAML Designer (Design tab) | Not yet supported | The Visual Studio XAML Designer doesn't currently support WinUI 3 projects. [XAML Hot Reload](/visualstudio/xaml-tools/xaml-hot-reload) is supported and is the recommended way to iterate on layout and styles without stopping the debugger. |
82+
| Blend for Visual Studio | ⚠️ Limited support | Blend ships with Visual Studio and can open WinUI 3 projects. The XAML Document Outline is functional, but Design view is not available for WinUI 3. |
83+
84+
## See also
85+
86+
- [Use the Windows App SDK in a WPF app](wpf-plus-winappsdk.md)
87+
- [Overall migration strategy](overall-migration-strategy.md)
88+
- [Windows Community Toolkit](/dotnet/communitytoolkit/introduction)
89+
- [XAML Behaviors (Community Toolkit)](https://aka.ms/toolkit/behaviors)

0 commit comments

Comments
 (0)