Last Updated 06 November 2021 | License CC BY-SA 4.0
The Universal Windows Platform (UWP) has its roots in SilverLight instead of being based on the Windows Presentation Foundation (WPF). UWP is implemented natively in C++ instead of WPF which was written in C# and C++ for lower-level functions. Due to being a completely different implementation of XAML, designed to include more resource constrained devices, and support for more programming languages, there are several differences in UWP compared to WPF. These differences may be new functionality in UWP, slightly different ways of doing things or, more commonly, WPF features missing in UWP. These differences are not summarized by Microsoft which is prohibitive for developers familiar with WPF and that have to port existing code. This document is intended to provide an overview of the differences.
This section lists the main differences (primarily from a XAML viewpoint) between UWP and WPF.
Legend:
- ✔ Indicates the platform (defined by the WPF or UWP column) has the feature
- ❌ Indicates the feature is generally missing in the platform
- ⚡ Indicates the feature is only partially implemented compared to other platforms
Item | WPF | UWP | Notes |
---|---|---|---|
x:Array Extension | ✔ | ❌ | x:Array isn't supported in UWP. |
x:Bind Extension | ❌ | ✔ | The x:Bind markup extension has become a powerful feature of UWP over WPF. Compiled function bindings can be used for nearly anything and can replace other missing features like MultiBinding in most situations. Other advantages of x:Bind include debugging support as well as increased performance because it's compiled. UWP originally did not support x:Bind in control templates; however, support was added in Windows 10 version 1809. |
x:Load Attribute | ❌ | ✔ | You can use x:Load to optimize the startup, visual tree creation, and memory usage of your XAML app. Using x:Load has a similar visual effect to Visibility, except that when the element is not loaded, its memory is released and internally a small placeholder is used to mark its place in the visual tree. |
x:Static Extension | ✔ | ❌ | The x:Static markup extension isn't implemented in UWP. In WPF this is used to access a static by-value code entity (constant, property, field, or enum). |
x:Type Extension | ✔ | ❌ | The x:Type markup extension isn't implemented in UWP. In WPF this is used to get a type similar to `Type.GetType()`. |
x:TypeArguments Directive | ✔ | ❌ | The x:TypeArguments directive isn't implemented in UWP which causes problems with generics. Missing this requires some work-arounds with classes and creating a non-generic class to use in XAML from a generic one. |
x:Uid Directive / .resw for localization | ⚡ | ✔ | x:Uid exists in both WPF and UWP. However, using it to localize properties is quite a bit more complex in WPF (using LocBaml, csv files, the commmand line in a manual process). UWP provides a much more integrated localization system using x:Uid and .resw files similar to what existed in Windows Forms. WPF is sorely missing this type of localization support and this is a clear advantage of UWP. |
{DynamicResource} Extension | ✔ | ❌ | The DynamicResource markup extension resolves and assigns the resource value to a XAML attribute at runtime only when its needed (as opposed to StaticResource which is resolved and assigned when XAML is first loaded). DynamicResource is fairly common in WPF but doesn't exist in UWP. A partial work-around requires custom markup extensions. |
{ThemeResource} Extension | ❌ | ✔ | The ThemeResource markup extension resolves and assigns the resource value to a XAML attribute depending on the active theme (light/dark/high-contrast). Resource values are automatically re-evaluated when the theme changes. |
Full Markup Extension | ✔ | ❌ | UWP only implements a subset of the full markup extension support in WPF. This area needs to be expanded upon in the future. |
Item | WPF | UWP | Notes |
---|---|---|---|
Coercion | ✔ | ❌ | Coercion of Dependency Properties is not supported in UWP. |
Data (Input) Validation | ✔ | ❌ | The entire WPF data validation system including the classes/inferfaces: ValidationRule (and all standard implementations), Binding.ValidationRules, IDataErrorInfo, INotifyDataErrorInfo, Binding.ValidatesOnNotifyDataErrors, etc. is not implemented in UWP. This will be added in WinUI 3.0 but the story for using this within the UWP app model with WinUI 3.0 is less clear. |
DependencyProperty. RegisterReadOnly / DependencyPropertyKey | ✔ | ❌ | Read-only dependency properties are used in WPF for collections and other properties that should never be set, even through binding. It is especially useful for control development. UWP doesn't support this and only implements get-only property accessors which still allow unwanted changes with binding. |
OneWayToSource BindingMode | ✔ | ❌ | |
Binding to ConverterParameter | ✔ | ❌ | |
MultiBinding / IMultiValueConverter | ✔ | ❌ | Very useful feature in WPF for advanced binding scenearios no longer exists for UWP. UWP does have function binding with x:Bind though (Used to re-implement converter logic). |
ICommand | ✔ | ⚡ | While the interface technically exists, ICommand is nothing like what it was in WPF. The programmer is now responsible for doing every little part of the command. This was improved in Windows 10 version 1809 which added XamlUICommand and StandardUICommand. |
RelativeSource / AncestorType | ✔ | ⚡ | Not nearly as powerful in UWP, relative source only supports `{RelativeSource Self}` and `{RelativeSource TemplatedParent}` as compared to more powerful expressions in WPF like `{RelativeSource PreviousData}` or `{Binding RelativeSource={RelativeSource Mode=PreviousData, AncestorType={x:Type TextBox}}`. |
StringFormat | ✔ | ❌ | XAML such as `{Binding DateValue, StringFormat=Date: {0:dddd yyyy-MM-dd}}` isn't supported in UWP and requires custom converters. |
Item | WPF | UWP | Notes |
---|---|---|---|
DataTriggers / PropertyTrigger / EventTrigger within Style.Triggers | ✔ | ❌ | |
VisualStateManager | ⚡ | ✔ | A different concept from WPF that takes the place of DataTriggers, this is very verbose and more often than not increases complexity compared to data triggers.
@Felix-Dev VisualStateManager does exist in WPF (it was added in .NET Framework 4.0). It's not as elegant as in UWP though, i.e. it has no VisuaStateManager.Setters property. That means you have to use Storyboards to set your values. |
Implicit DataTemplate | ✔ | ❌ | Set the DataType property of the DataTemplate to the corresponding type and the template is then applied automatically to all instances of that particular type |
Binding in Style setter | ✔ | ❌ | Any other than TemplateBinding isn't support in a template/style within UWP |
BasedOn default Style | ✔ | ⚡ | `BasedOn={StaticResource {x:Type TextBlock}` isn't supported in UWP but works in WPF. Instead, BasedOn requires the use of a key which is a problem as not all default styles define one. This is a specific example of the missing x:Type markup extension in UWP. |
This section primarily describes differences in controls and properties at the object or class level. As the number of differences in this section may become quite large, classes and properties are listed alphabetically and grouped together where it makes sense. Only the most used and fundamental controls are included here. See the Controls section for a high-level understanding of all controls.
Grid
Item | WPF | UWP | Notes |
---|---|---|---|
BorderBrush | ❌ | ✔ | This property does not exist in WPF's Grid. It was added in UWP to help flatten the visual tree instead of requiring the use of a Border. |
BorderThickness | ❌ | ✔ | This property does not exist in WPF's Grid. It was added in UWP to help flatten the visual tree instead of requiring the use of a Border. |
ColumnSpacing / RowSpacing | ❌ | ✔ | Similar to StackPanel.Spacing, the Grid's ColumnSpacing and RowSpacing properties provide a quick way to set a uniform horizortal and/or vertical distance between all child controls in a Grid. This was added to UWP and does not exist in WPF. |
CornerRadius | ❌ | ✔ | This property does not exist in WPF's Grid. It was added in UWP to help flatten the visual tree instead of requiring the use of a Border. |
Padding | ❌ | ✔ | This property does not exist in WPF's Grid. It was added in UWP to help flatten the visual tree instead of requiring the use of a Border. |
ShowGridLines | ✔ | ❌ | While this property exists in WPF, it was only intended for debugging purposes and not production quality code (https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.grid.showgridlines). As such, it was removed from UWP. |
StackPanel
Additional properties such as WPF's HasLogicalOrientation
, HorizontalOffset
and VerticalOffset
are purposely excluded from this section as they aren't considered useful.
Item | WPF | UWP | Notes |
---|---|---|---|
AreHorizontalSnapPointsRegular / AreScrollSnapPointsRegular / AreVerticalSnapPointsRegular | ❌ | ✔ | Information on snapping points does not exist in WPF's StackPanel. |
BackgroundSizing | ❌ | ✔ | https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.stackpanel.backgroundsizing |
BorderBrush | ❌ | ✔ | This property does not exist in WPF's StackPanel. It was added in UWP to help flatten the visual tree instead of requiring the use of a Border. |
BorderThickness | ❌ | ✔ | This property does not exist in WPF's StackPanel. It was added in UWP to help flatten the visual tree instead of requiring the use of a Border. |
CornerRadius | ❌ | ✔ | This property does not exist in WPF's StackPanel. It was added in UWP to help flatten the visual tree instead of requiring the use of a Border. |
ExtentHeight | ✔ | ❌ | https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.stackpanel.extentheight |
ExtentWidth | ✔ | ❌ | https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.stackpanel.extentwidth |
Padding | ❌ | ✔ | This property does not exist in WPF's StackPanel. It was added in UWP to help flatten the visual tree instead of requiring the use of a Border. |
Spacing | ❌ | ✔ | The Spacing property is a quick way to set a uniform distance between all child controls in a StackPanel. This was added to UWP and does not exist in WPF. |
UIElement
Item | WPF | UWP | Notes |
---|---|---|---|
IsVisible / IsVisibleChanged Event | ✔ | ❌ | UWP has no way of tracking which controls are actually visible on the display. WPF has the UIElement.IsVisible property and the IsVisibleChanged event. This hinders the ability to optimize controls for performance. |
Visibility with Visibility.Hidden | ✔ | ⚡ | UWP does not include the Visibility.Hidden enum value used for UIElement.Visibility. Hidden in WPF allowed a control to still be used in measure/layout but appear invisible when rendered for display. |
Clip | ✔ | ⚡ | Both WPF and UWP have UIElement.Clip properties. However, WPF can take any Geometry allowing for non-rectangular clipping. UWP can only use a RectangleGeometry for clipping. WPF: public Geometry UIElement.Clip, UWP: public RectangleGeometry UIElement.Clip |
ClipToBounds | ✔ | ❌ | In WPF it's possible to clip child contents to the parents bounds by setting ClipToBounds to True. UWP doesn't have this property at all. The work-around is to use UIElement.Clip which can only do rectangular clipping. |
LayoutTransform | ✔ | ❌ | Layout transform is needed to transform elements before layouting. This allows for easily changing textbox direction and then putting it in a table. RenderTransform, as it applies after layout, does not resize parent controls for transformed children. See Transform3D for the UWP equivalent. |
Projection | ❌ | ✔ | A 3-D projection effect applied to the element. Is more or less obsolete, use Transform3D instead. |
Transform3D | ❌ | ✔ | Use the Transform3D property to apply a 3-D transform matrix to a XAML element. This lets you create effects where two-dimensional UI appears to exist in 3-D space relative to the user. Transform3D behaves much like RenderTransform, but allows transforms in three-dimensional space and not just two dimensions. It also support animations. |
Minor Changes
Item | WPF | UWP | Notes |
---|---|---|---|
Header / HeaderTemplate | ❌ | ✔ | Several controls in UWP support an additional Header content and HeaderTemplate property. This allows for quickly adding a description or title above a control which is useful in data-input scenarios. UWP controls with a header property include: ComboBox, DatePicker, ListViewBase, PasswordBox, TextBox, TimePicker, ToggleSwitch. Notably, the header property is not present on some controls such as: Button and CheckBox. |
ItemsControl. AlternationIndex / AlternationCount | ✔ | ❌ | WPF has an easy way to change the style of items in a list using ItemsControl.AlternationIndex and ItemsControl.AlternationCount. This allows, for example, to change the background color of a listed item for even/odd entries. UWP doesn't support this at all in any controls. The partial work-around in UWP is to create a new control deriving from the framework's implementation and override the PrepareContainerForItemOverride() method. |
Thickness | ✔ | ⚡ | The Thickness struct exposes fields for Top, Bottom, Left and Right instead of dependency properties as in WPF. This means you cannot Bind or asign resources to an individual thickness parameter. |
Size / Rect / Point | ✔ | ✔ | Size, Rect and Point are fully supported in both WPF and UWP. However, UWP uses single-precision float types for properties instead of double in WPF. This creates an incompatiblity when porting code. |
Unimplemented Classes
Item | WPF | UWP | Notes |
---|---|---|---|
Adorner | ✔ | ❌ | https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/adorners-overview |
Supplemental Shapes: Arrow, Callout, Star, etc | ✔ | ❌ | Several shapes present in WPF are missing in UWP. |
VisualBrush / DrawingBrush | ✔ | ❌ | VisualBrush is not a XAML brush in UWP. Instead, must fall back to composition brushes which are not 1:1 equivalent. DrawingBrush is not supported at all in UWP. |
Window | ✔ | ❌ | For some good reasons UWP has no concept of a window. This is fine for mobile devices but can be a problem for purely desktop applications. Without a window, there is no way to control an app's size or position. There are currently proposals to add this in the transition to WinUI 3.0. |
Item | WPF | UWP | Notes |
---|---|---|---|
Custom Cursor at runtime | ✔ | ❌ | |
Sub-pixel anti-aliasing | ✔ | ❌ | Anti-aliasing in UWP along with rendering in general is poor compared to WPF. It's assumed this is for performance reasons on mobile devices and the web (Silverlight). |
Nested Types in XAML | ✔ | ❌ | Nesting different types in XAML is generally not possible in UWP. Code such as `<ListBox.ItemsSource><x:Array><s:string>foo<s/:string><x/:Array>` works in WPF but not in UWP. |
Event Tunneling / Event Bubbling / Routed Events | ✔ | ⚡ | A lot more events are simply direct in UWP. Some cases of event bubbling such as ButtonBase.Click to parent are not supported in UWP. Event Tunneling, a concept fully supported in WPF, isn't support at all in UWP. |
- Several UWP controls have reentrancy issues. For example, changing the selected item while in a ComboBox SelectionChanged event is largely not possible and will result in a crash. This makes validation directly in the event handler nearly impossible.
- UWP controls are generally not as powerful as the WPF counterparts. For example, for several years the ComboBox in UWP was not editable. The UWP DatePicker also does not allow typing in a specific date.
- UWP has no support for data (input) validation. This is a large issue for line-of-business apps migrating from WPF to UWP that heavily use this feature in view models or binding.
- The UWP styling system is different enough from WPF to require extra effort during porting. UWP uses the VistualStateManger instead of concepts like DataTriggers or EventTriggers from WPF. Styling/Templating are one of the main differences.
- The ResourceDictionary XAML markup in UWP supports far fewer features than in WPF.
- UWP seems to follow only the XAML/2006 spec instead of XAML/2009 supported by WPF
- Several UWP controls are sealed and new controls cannot derive from them
- For advanced rendering, UWP has fewer features built in. This requires falling back to Win2D or composition more often.
- There are several namespaces differences in UWP and WPF. For example, WPF has System.Windows.Media.Colors while UWP moves this to Windows.UI.Colors.
- TextBlock and TextBox, for example, do not allow 'null' values for string-type Text properties. Setting null to
Text
will crash the app at runtime. This is one of the largest concerns when porting over from WPF as WPF accepts null without an issue; yet the same code may crash in UWP. The solution is to use.Text = stringValue ?? string.Empty;
for all controls instead of setting a string directly. - In WPF it was possible to build templates using the FrameworkElementFactory Class without using XAML. This allowed for entire UI's to be created without markup (since instantiating controls is already possible in C# directly). However, the burden of maintaining two different ways of doing things became too much and Microsoft dropped this ability in UWP and deprecated it for WPF. Instead, it's necessary to write template XAML as a string in code then pass it to XamlReader.Load().
- In WPF it was possible to get the reference to a control generated from a template using
Control.Template.FindName("controlName")
. This was very useful combined with data binding when you needed to get a control instance. In UWPTemplate.FindName
does not exist. This means to get the control generated from a template you must walk the visual tree usingVisualTreeHelper.GetChild()
. In practice this introduces a timing factor and makes it more difficult than in WPF (you must be sure the template is fully generated).
For a list of supported controls and a comparison of their differences, refer to the separate XAML Framework Controls document. This document was originally included here but was separated to allow expansion and inclusion of other frameworks.
This document is licensed CC BY-SA 4.0. For full text see: https://creativecommons.org/licenses/by-sa/4.0/legalcode