---
uid: Uno.Development.WPFWinUIEquivalents
---
# WPF to WinUI XAML Equivalents Reference
This reference provides a comprehensive mapping of WPF namespaces, controls, XAML syntax, events, and patterns to their WinUI 3 / Uno Platform equivalents. Use it as a lookup when migrating WPF applications.
> [!TIP]
> For architectural migration guidance (MVVM, navigation, data access), see [Migrating WPF Apps to Web](wpf-migration.md).
## Namespace Mapping
| WPF Namespace | WinUI 3 Namespace | Notes |
|---|---|---|
| `System.Windows` | `Microsoft.UI.Xaml` | Root namespace |
| `System.Windows.Controls` | `Microsoft.UI.Xaml.Controls` | Core controls |
| `System.Windows.Controls.Primitives` | `Microsoft.UI.Xaml.Controls.Primitives` | Low-level primitives |
| `System.Windows.Media` | `Microsoft.UI.Xaml.Media` | Brushes, transforms |
| `System.Windows.Media.Animation` | `Microsoft.UI.Xaml.Media.Animation` | Storyboard, animations |
| `System.Windows.Media.Imaging` | `Microsoft.UI.Xaml.Media.Imaging` | BitmapImage, WriteableBitmap |
| `System.Windows.Media.Media3D` | `Microsoft.UI.Xaml.Media.Media3D` (partial equivalent) | Supports 3D transforms/projection (for example `CompositeTransform3D`, `Matrix3D`, `PerspectiveTransform3D`), but not WPF-style `Viewport3D` / 3D scene graph APIs |
| `System.Windows.Shapes` | `Microsoft.UI.Xaml.Shapes` | Rectangle, Ellipse, Path |
| `System.Windows.Data` | `Microsoft.UI.Xaml.Data` | Binding, IValueConverter |
| `System.Windows.Input` | `Microsoft.UI.Xaml.Input` | Pointer, keyboard, focus |
| `System.Windows.Navigation` | No direct equivalent | Use `Frame.Navigate()` |
| `System.Windows.Documents` | Limited | `RichTextBlock` + `Paragraph` |
| `System.Windows.Markup` | `Microsoft.UI.Xaml.Markup` | XAML parsing, markup extensions |
| `System.Windows.Automation` | `Microsoft.UI.Xaml.Automation` | Accessibility / UI Automation |
| `System.Windows.Interop` | `Microsoft.UI.Xaml.Hosting` | Interop / XAML Islands |
| `System.Windows.Threading` | `Microsoft.UI.Dispatching` | `Dispatcher` becomes `DispatcherQueue` |
### XAML Declaration Syntax
| WPF | WinUI |
|---|---|
| `xmlns:local="clr-namespace:MyApp"` | `xmlns:local="using:MyApp"` |
| `xmlns:local="clr-namespace:MyApp;assembly=MyLib"` | `xmlns:local="using:MyApp"` (assembly inferred) |
## Control Mappings
### Controls That Transfer Directly
These controls exist in both WPF and WinUI and typically require only a namespace change:
Button, TextBox, TextBlock, CheckBox, RadioButton, ComboBox, ListBox, ListView, Grid, StackPanel, Border, ScrollViewer, Canvas, Image, Slider, ProgressBar, ToolTip/ToolTipService, Expander, TreeView.
### WinUI-Only Additions You May Want to Adopt
The following controls do not have direct equivalents in WPF but are often valuable to introduce when modernizing your UI with WinUI / Uno Platform:
NavigationView, NumberBox, InfoBar, ProgressRing, ToggleSwitch, HyperlinkButton, GridView.
### Controls Requiring Replacement
| WPF Control | WinUI / Uno Replacement | Notes |
|---|---|---|
| `DataGrid` | Community Toolkit `DataGrid` | Similar API, not identical. In WinUI 3 (Windows App SDK), use `CommunityToolkit.WinUI.UI.Controls`; for Uno Platform non-Windows targets, use the Uno-ported toolkit packages (`Uno.CommunityToolkit.WinUI.*`). |
| `Ribbon` | `CommandBar` or `NavigationView` | No Ribbon in WinUI |
| `Menu` / `MenuItem` | `MenuBar` / `MenuBarItem` / `MenuFlyoutItem` | `MenuBar` for top-level menus; `MenuFlyout` for context menus |
| `ContextMenu` | `MenuFlyout` via `ContextFlyout` property | Assign to `ContextFlyout` on any `UIElement` |
| `ToolBar` / `ToolBarTray` | `CommandBar` + `AppBarButton` | |
| `StatusBar` | Custom `Grid` / `StackPanel` or `InfoBar` | No StatusBar control in WinUI |
| `TabControl` | `TabView` or `NavigationView` (Top mode) | `TabView` supports closable tabs |
| `DocumentViewer` | `WebView2` | Can display PDFs in WebView2; XPS requires conversion or a dedicated/third-party viewer |
| `FlowDocument` | `RichTextBlock` | Partial replacement only |
| `RichTextBox` | `RichEditBox` | Rich text editing |
| `WrapPanel` | `WrapPanel` (built-in on Uno Platform) or Community Toolkit `WrapPanel` | Built-in on Uno Platform; otherwise see package guidance below. |
| `UniformGrid` | Community Toolkit `UniformGrid` | Not in WinUI by default; see package guidance below. |
| `DockPanel` | Community Toolkit `DockPanel` | Not in WinUI by default; see package guidance below. |
| `GroupBox` | `Expander` or a custom `UserControl`/templated `ContentControl` | No built-in GroupBox in WinUI; use a custom header + border presentation when needed |
| `Label` | `TextBlock` | Use `TextBlock` for the visual label; for WPF `Label.Target`-style association, use `AutomationProperties.LabeledBy` on the labeled control. `AccessKey` can be added separately for keyboard access. |
| `MediaElement` | `MediaPlayerElement` | Different API surface |
| `Window` (standalone) | `Window` | Window host; content is typically a `Page`/root `UIElement`. Use `ContentDialog` for modal windows. |
| `GridSplitter` | Community Toolkit `GridSplitter` | See package guidance below. |
| `Calendar` | `CalendarView` | Similar functionality with updated API |
| `ListBox` | `ListBox` or `ListView` | `ListBox` exists in WinUI/Uno; prefer `ListView` when you need richer built-in list item presentation or interaction features |
Package guidance for Community Toolkit controls in this table: in WinUI 3 (Windows App SDK), use `CommunityToolkit.WinUI.UI.Controls`; for Uno Platform non-Windows targets, install the matching Uno package for the control you use, such as `Uno.CommunityToolkit.WinUI.UI.Controls` for controls like `DockPanel` and `GridSplitter`, or `Uno.CommunityToolkit.WinUI.UI.Controls.DataGrid` for `DataGrid`. See [Uno Community Toolkit packages](uno-community-toolkit.md) for the authoritative package list and version guidance.
### Useful NuGet Packages
| Package | Purpose |
|---|---|
| `CommunityToolkit.WinUI.UI.Controls` | DataGrid, WrapPanel, DockPanel, UniformGrid. Note: `DataGrid` and some related controls are available in Windows Community Toolkit 7.x; they were removed from 8.x. |
| `CommunityToolkit.Mvvm` | RelayCommand, ObservableObject, source generators |
| `Uno.Material.WinUI`, `Uno.Cupertino.WinUI`, `Uno.Simple.WinUI` | Material, Cupertino, or simple theme support |
| `Uno.Toolkit.WinUI` | Additional cross-platform controls and helpers |
## Property and Value Mappings
| WPF Property / Value | WinUI Equivalent | Context |
|---|---|---|
| `Visibility.Hidden` | Not available | Use `Opacity="0"` together with `IsHitTestVisible="False"` (and, for focusable controls, `IsTabStop="False"`) to be invisible, non-interactive, but still layout-occupying. |
| `TextWrapping.WrapWithOverflow` | `TextWrapping.Wrap` | WinUI does not distinguish |
| `Focusable` | `IsTabStop` and, when preventing interaction focus, `AllowFocusOnInteraction` | `IsTabStop` controls keyboard tab navigation; to also prevent focus via pointer interaction in WinUI/Uno, typically use `AllowFocusOnInteraction="False"` as well (and `IsTabStop="False"` where applicable). |
## Event Mappings
### Pointer Events (Replacing Mouse Events)
| WPF Event | WinUI Event | Args Type |
|---|---|---|
| `MouseLeftButtonDown` | `PointerPressed` | `PointerRoutedEventArgs` |
| `MouseLeftButtonUp` | `PointerReleased` | `PointerRoutedEventArgs` |
| `MouseMove` | `PointerMoved` | `PointerRoutedEventArgs` |
| `MouseEnter` | `PointerEntered` | `PointerRoutedEventArgs` |
| `MouseLeave` | `PointerExited` | `PointerRoutedEventArgs` |
| `MouseWheel` | `PointerWheelChanged` | `PointerRoutedEventArgs` |
| `MouseDoubleClick` | `DoubleTapped` | `DoubleTappedRoutedEventArgs` |
| `PreviewMouseDown` | `PointerPressed` | No direct WPF-style tunneling/preview pointer event in WinUI |
> [!NOTE]
> WinUI does not provide WPF-style `PreviewMouse*` tunneling events for pointer/mouse input. If you need to listen for a bubbling event even after a child marks it handled, use `AddHandler` with `handledEventsToo: true`. This does not reproduce WPF-style preview ordering (parent before child).
### Keyboard Events
| WPF Event | WinUI Event | Args Type |
|---|---|---|
| `KeyDown` | `KeyDown` | `KeyRoutedEventArgs` |
| `KeyUp` | `KeyUp` | `KeyRoutedEventArgs` |
| `PreviewKeyDown` | `Uno only (WASM/SKIA): PreviewKeyDown` | `KeyRoutedEventArgs` |
| `PreviewKeyUp` | `Uno only (WASM/SKIA): PreviewKeyUp` | `KeyRoutedEventArgs` |
> [!NOTE]
> Standard WinUI 3 does not expose WPF-style preview keyboard events. On Uno, `PreviewKeyDown` and `PreviewKeyUp` are available only on some targets (for example, WASM/SKIA), so treat them as platform-specific rather than general WinUI equivalents. When you need a cross-target or WinUI 3-compatible alternative, use `KeyDown` and `KeyUp`, and validate event ordering on your target platforms when the distinction matters.
### Mouse Capture
| WPF | WinUI | Notes |
|---|---|---|
| `element.CaptureMouse()` | `element.CapturePointer(e.Pointer)` | Typically used inside a pointer event where `e.Pointer` is available |
| `element.ReleaseMouseCapture()` | `element.ReleasePointerCaptures()` | General equivalent when you do not have the original `Pointer`; if you need to release a specific pointer later, store it and call `element.ReleasePointerCapture(pointer)` |
| `Mouse.GetPosition(element)` | `e.GetCurrentPoint(element).Position` | Use within pointer event handling |
## XAML Syntax Translations
### Resource and Binding Markup
| WPF | WinUI | Notes |
|---|---|---|
| `{StaticResource Key}` | `{StaticResource Key}` | Identical - resolved once at load |
| `{DynamicResource Key}` | `{ThemeResource Key}` | Re-evaluated on theme changes (Light/Dark) |
| `{x:Static ns:Type.Member}` | `{x:Bind ns:Type.Member}` | Common option for static member references; enums/values can often use direct `ns:Type.Member` or literals |
| `{Binding Path=X}` | `{x:Bind ViewModel.X, Mode=OneWay}` | See [binding comparison](#binding-technology-comparison) below |
| `{Binding RelativeSource={RelativeSource AncestorType=...}}` | Uno Toolkit `AncestorSource` | See [Ancestor/ItemsControl binding](https://github.com/unoplatform/uno.toolkit.ui/blob/main/doc/helpers/ancestor-itemscontrol-binding.md) |
### Binding Technology Comparison
| Feature | `{Binding}` | `{x:Bind}` |
|---|---|---|
| Compile-time validation | No | Yes |
| Default mode | Depends on target property metadata (often OneWay; some are TwoWay) | **OneTime** |
| Default source | DataContext | Page / UserControl code-behind |
| Function binding | No | Yes |
| Performance | Reflection-based | Compiled, no reflection |
| MultiBinding | Not in WinUI | Use function binding |
> [!IMPORTANT]
> `{x:Bind}` defaults to **OneTime**, not OneWay. Always specify `Mode=OneWay` for properties that should update.
## Patterns Without Direct WinUI Equivalents
### Style.Triggers and DataTriggers
WinUI does not support `Style.Triggers`, `DataTrigger`, `EventTrigger`, or `MultiDataTrigger`. Replace with `VisualStateManager`:
**WPF:**
```xml
```
**WinUI equivalent:**
```xml
```
### MultiBinding
WinUI does not support `MultiBinding`. Use `x:Bind` with function binding:
```xml
```
```csharp
public static class Converters
{
public static string FormatFullName(string first, string last)
=> $"{first} {last}";
}
```
### RoutedUICommand
Replace `RoutedUICommand` and `CommandBinding` with `ICommand` implementations. Using CommunityToolkit.Mvvm:
```csharp
[RelayCommand(CanExecute = nameof(CanSave))]
private void Save() { /* save logic */ }
private bool CanSave() => IsDirty;
```
WinUI 3 also offers `StandardUICommand` and `XamlUICommand` for predefined operations (Cut, Copy, Paste) with built-in icons and keyboard accelerators.
### Adorners
WinUI does not have an Adorner layer. Use these alternatives:
| Adorner Use Case | WinUI Replacement |
|---|---|
| Validation indicators | `TeachingTip`, `InfoBar`, or input validation templates |
| Resize handles | `Popup` positioned relative to target |
| Drag preview | `DragItemsStarting` event with custom DragUI |
| Overlay decorations | Canvas overlay or `Popup` layer |
| Watermark / Placeholder | `TextBox.PlaceholderText` (built-in) |
## Resource Dictionaries
```xml
```
Key differences from WPF:
- `XamlControlsResources` must be the **first** merged dictionary to provide default styles. Omitting it leaves controls with no visual appearance.
- Resource paths use `ms-appx:///` protocol instead of relative paths.
- `Window.Resources` does not exist in WinUI. Place window-level resources on root layout containers or `Page`.
### Implicit Styles and BasedOn
Always use `BasedOn` when overriding default control styles. Without it, your style **replaces** the entire default style rather than extending it:
```xml
```
## Common API Replacements
| WPF Code | WinUI Replacement | Notes |
|---|---|---|
| `Application.Current.Dispatcher.Invoke(...)` | `App.MainWindow.DispatcherQueue.TryEnqueue(...)` | Fire-and-forget; no synchronous `Invoke`. See awaitable example below. |
| `Application.Current.MainWindow` | `App.MainWindow` (captured at startup) | Use the app's main window reference in WinUI/Uno. |
| `Clipboard` (System.Windows) | `Windows.ApplicationModel.DataTransfer.Clipboard` | Different API surface |
| `MessageBox.Show()` | `ContentDialog` with `XamlRoot` | No MessageBox in WinUI |
For awaitable dispatch, wrap `DispatcherQueue.TryEnqueue(...)` with a `TaskCompletionSource`:
```csharp
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
if (!App.MainWindow.DispatcherQueue.TryEnqueue(() =>
{
try
{
/* work */
tcs.TrySetResult(true);
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
}))
{
tcs.TrySetException(new InvalidOperationException("Failed to enqueue work on the DispatcherQueue."));
}
await tcs.Task;
```
## Find-and-Replace Quick Reference
### XAML Attribute Replacements
| Find | Replace With | Notes |
|---|---|---|
| `ContextMenu=` | `ContextFlyout=` | |
| `{DynamicResource` | `{ThemeResource` | |
| `{x:Static` | `{x:Bind` | |
| `Visibility="Hidden"` (layout-preserving) | `Opacity="0"` with `IsHitTestVisible="False"` | Keeps layout space; combine with `IsTabStop="False"` for focusable controls |
| `Visibility="Hidden"` (remove from layout) | `Visibility="Collapsed"` | Collapses space like WPF `Visibility="Collapsed"` |
| `MouseLeftButtonDown` | `PointerPressed` | |
| `MouseLeftButtonUp` | `PointerReleased` | |
| `MouseEnter` | `PointerEntered` | |
| `MouseLeave` | `PointerExited` | |
| `MouseMove` | `PointerMoved` | |
| `MouseWheel` | `PointerWheelChanged` | |
| `Focusable="True"` | `IsTabStop="True"` | |
| `TextWrapping="WrapWithOverflow"` | `TextWrapping="Wrap"` | |
| `MediaElement` | `MediaPlayerElement` | |
| `InputBindings` | `KeyboardAccelerators` | |
| `KeyBinding` | `KeyboardAccelerator` | |
### Code-Behind Replacements
| Find | Replace With |
|---|---|
| `using System.Windows;` | `using Microsoft.UI.Xaml;` |
| `using System.Windows.Controls;` | `using Microsoft.UI.Xaml.Controls;` |
| `using System.Windows.Media;` | `using Microsoft.UI.Xaml.Media;` |
| `using System.Windows.Data;` | `using Microsoft.UI.Xaml.Data;` |
| `using System.Windows.Input;` | `using Microsoft.UI.Xaml.Input;` |
| `Dispatcher.Invoke(` | `DispatcherQueue.TryEnqueue(` |
| `MouseEventArgs` | `PointerRoutedEventArgs` |
| `KeyEventArgs` | `KeyRoutedEventArgs` |
| `RoutedUICommand` | `RelayCommand` (CommunityToolkit.Mvvm) |
| `CommandBinding` | Remove; bind `ICommand` directly |
## AI Prompt Template
Use this prompt with an AI coding assistant to automate the mechanical translation of WPF XAML files:
````text
You are a WPF-to-WinUI XAML migration assistant. Translate the following WPF XAML
file to WinUI 3 XAML compatible with Uno Platform.
Apply ALL of the following rules:
NAMESPACE RULES:
- Keep the default xmlns as-is
- Replace clr-namespace references with "using:" syntax
- Replace System.Windows.* with Microsoft.UI.Xaml.*
RESOURCE RULES:
- Replace {DynamicResource X} with {ThemeResource X}
- Replace {x:Static X} with {x:Bind X}
- Keep {StaticResource X} as-is
CONTROL REPLACEMENTS:
- Menu/MenuItem -> MenuBar/MenuBarItem/MenuFlyoutItem
- ContextMenu -> ContextFlyout with MenuFlyout
- ToolBar -> CommandBar with AppBarButton
- StatusBar -> Grid at bottom of layout
- TabControl -> TabView or NavigationView (Top mode)
- DataGrid -> CommunityToolkit DataGrid
- Label -> TextBlock
- MediaElement -> MediaPlayerElement
PROPERTY REPLACEMENTS:
- Visibility="Hidden" -> WinUI has no direct `Hidden` state; when layout must be preserved, use `Opacity="0"` with `Visibility="Visible"` and also set `IsHitTestVisible="False"`; for focusable controls also set `IsTabStop="False"` and `AllowFocusOnInteraction="False"` so the element is not invisible-but-interactive; use `Visibility="Collapsed"` only when removing the element from layout is acceptable
- TextWrapping="WrapWithOverflow" -> TextWrapping="Wrap"
- Focusable -> IsTabStop
EVENT REPLACEMENTS:
- Mouse* events -> Pointer* equivalents
- Remove Preview* tunneling events
TRIGGER REPLACEMENTS:
- Remove Style.Triggers, DataTrigger, EventTrigger
- Create VisualStateManager.VisualStateGroups with StateTrigger
BINDING UPGRADES:
- Convert {Binding Path=X} to {x:Bind ViewModel.X, Mode=OneWay}
- Replace MultiBinding with x:Bind function binding
OUTPUT: Complete translated XAML with a list of manual follow-up items.
WPF XAML to translate:
```xml
```
````
## FAQ
**Do I need to rewrite all my XAML from scratch?**
No. The majority of WPF XAML transfers with namespace changes and minor property fixes. The heavy lifting is in triggers, MultiBinding, and controls that don't exist in WinUI.
**Can I keep using {Binding} or must I switch to {x:Bind}?**
`{Binding}` still works and is not mandatory to replace. However, `{x:Bind}` provides compile-time validation, better performance, and function binding (which replaces MultiBinding). For new or migrated code, `{x:Bind}` is recommended.
**What replaces Visibility.Hidden?**
WinUI only has `Visible` and `Collapsed`. For invisible-but-layout-occupying behavior, set `Opacity="0"` while keeping `Visibility="Visible"`, and also set `IsHitTestVisible="False"`. If the control can receive focus, also set `IsTabStop="False"` and `AllowFocusOnInteraction="False"` so it does not remain invisible but interactive.
**How do I handle preview/tunneling events?**
WinUI 3 does not generally provide WPF-style preview/tunneling events. In Uno Platform, some preview keyboard events such as `PreviewKeyDown` and `PreviewKeyUp` are available on specific targets only, so they should not be treated as a general WinUI 3 migration equivalent. For cross-target and WinUI 3-compatible code, use `KeyDown`/`KeyUp` instead. WPF-style preview mouse/pointer events such as `PreviewMouseDown` do not generally have direct equivalents; use the corresponding bubbling event (for example, `PointerPressed`) and, if you need to observe events that were already marked handled, register with `AddHandler(..., handledEventsToo: true)`.
**How do I migrate the Dispatcher pattern?**
Replace `Application.Current.Dispatcher.Invoke(...)` with `App.MainWindow.DispatcherQueue.TryEnqueue(...)`. The `DispatcherQueue` API is asynchronous by default and has no synchronous `Invoke` method.
**Does Uno Platform add controls beyond WinUI?**
Yes. The [Uno Toolkit](xref:Toolkit.GettingStarted) includes NavigationBar, TabBar, DrawerControl, SafeArea, and more. The [Community Toolkit](uno-community-toolkit.md) controls (DataGrid, WrapPanel, DockPanel) also work across all Uno Platform targets.