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.
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 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 below |
{Binding RelativeSource={RelativeSource AncestorType=...}} |
Uno Toolkit AncestorSource |
See Ancestor/ItemsControl binding |
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:
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding IsActive}" Value="True">
<Setter Property="Background" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
WinUI equivalent:
<Border x:Name="MyBorder">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="Active">
<VisualState.StateTriggers>
<StateTrigger IsActive="{x:Bind ViewModel.IsActive, Mode=OneWay}" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="MyBorder.Background" Value="Green" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
MultiBinding
WinUI does not support MultiBinding. Use x:Bind with function binding:
<TextBlock Text="{x:Bind local:Converters.FormatFullName(ViewModel.FirstName, ViewModel.LastName), Mode=OneWay}" />
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:
[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
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Required: default Fluent styles -->
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Your custom resources -->
<ResourceDictionary Source="ms-appx:///Styles/Colors.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Key differences from WPF:
XamlControlsResourcesmust 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.Resourcesdoes not exist in WinUI. Place window-level resources on root layout containers orPage.
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:
<Style TargetType="Button" BasedOn="{StaticResource DefaultButtonStyle}">
<Setter Property="Background" Value="Red" />
</Style>
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:
var tcs = new TaskCompletionSource<bool>(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:
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
<!-- Paste WPF XAML here -->
<PASTE WPF XAML HERE>
```
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 includes NavigationBar, TabBar, DrawerControl, SafeArea, and more. The Community Toolkit controls (DataGrid, WrapPanel, DockPanel) also work across all Uno Platform targets.