Comparaison entre WPF et UWP
Initialement basé sur UWPvsWPF.md avec des modifications spécifiques à Avalonia.
Ce document est sous licence CC BY-SA 4.0. Pour le texte complet de cette licence, voir : https://creativecommons.org/licenses/by-sa/4.0/legalcode
Cette section liste les principales différences (principalement du point de vue de XAML) entre Avalonia, UWP et WPF.
Légende :
- ✔ Indique que la plateforme (définie par la colonne Avalonia, WPF ou UWP) possède la fonctionnalité
- ✖ Indique que la fonctionnalité est généralement absente de la plateforme
- ⚡ Indique que la fonctionnalité est seulement partiellement implémentée par rapport aux autres plateformes
Extensions des balises
| Sujet | Avalonia | WPF | UWP | Notes |
|---|---|---|---|---|
| x:Uid pour la localisation | ✖ | ✖ | ✔ | x:uid est un système de localisation puissant similaire à ce qui existe dans Windows Forms. WPF manque cruellement de ce type de support de localisation. C'est un avantage clair de UWP. |
| x:Bind | ✖ | ✖ | ✔ | x:Bind est également devenu une fonctionnalité puissante de UWP par rapport à WPF. Les liaisons compilées peuvent être utilisées pour presque tout et peuvent remplacer d'autres fonctionnalités manquantes comme MultiBinding. D'autres avantages incluent le support du débogage ainsi qu'une performance accrue. |
| x:Array | ✖ | ✔ | ✖ | x:Array n'est pas supporté en UWP. |
| x:Static | ✔ | ✔ | ⚡ | x:Static pourrait être remplacé par x:Bind |
| x:Type | ✔ | ✔ | ✖ | |
| x:True | ✔ | ✖ | ✖ | |
| x:False | ✔ | ✖ | ✖ | |
| Extension de balisage complet | ✔ | ✔ | ✖ | UWP n'implémente qu'un sous-ensemble du support complet des extensions de balisage dans WPF. Ce domaine doit être élargi à l'avenir. |
| Bindings compilés | ✔ | ✖ | ✖ |
Binding
| Sujet | Avalonia | WPF | UWP | Notes |
|---|---|---|---|---|
| OneWayToSource BindingMode | ✔ | ✔ | ✖ | |
| Binding to ConverterParameter | ✔ | ✔ | ✖ | |
| MultiBinding / IMultiValueConverter | ✔ | ✔ | ✖ | Une fonctionnalité très utile dans WPF pour des scénarios de liaison avancés n'existe plus pour UWP. UWP dispose cependant de la liaison fonctionnelle avec x:Bind (Utilisé pour réimplémenter la logique du convertisseur). |
| ICommand | ✔ | ✔ | ⚡ | Bien que l'interface existe techniquement, ICommand n'est rien de comparable à ce qu'elle était dans WPF. Le programmeur est désormais responsable de chaque petite partie de la commande. Cela a été amélioré dans la version 1809 de Windows 10, qui a ajouté XamlUICommand et StandardUICommand. |
| RelativeSource / AncestorType | ✔ | ✔ | ⚡ | Pas aussi puissant dans UWP, la source relative ne prend en charge que {RelativeSource Self} et {RelativeSource TemplatedParent} par rapport à des expressions plus puissantes dans WPF comme {RelativeSource PreviousData} ou {Binding RelativeSource={RelativeSource Mode=PreviousData, AncestorType={x:Type TextBox}}. |
| StringFormat | ✔ | ✔ | ✖ | Le XAML tel que {Binding DateValue, StringFormat=Date: {0:dddd yyyy-MM-dd}} n'est pas pris en charge dans UWP et nécessite des convertisseurs personnalisés. |
| Fonctions pour le binding | ✖ | ✖ | ✔ | x:Bind dans UWP prend en charge la liaison de fonction OneWay et TwoWay qui peut remplacer les convertisseurs. |
Style
| Sujet | Avalonia | WPF | UWP | Notes |
|---|---|---|---|---|
| DataTriggers / PropertyTrigger / EventTrigger dans Style.Triggers | ✖ | ✔ | ✖ | |
| VisualStateManager | ✖ | ⚡ | ✔ | Un concept différent de WPF qui remplace les DataTriggers, cela est très verbeux et augmente souvent la complexité par rapport aux déclencheurs de données. @Felix-Dev VisualStateManager existe dans WPF (il a été ajouté dans .NET Framework 4.0). Ce n'est pas aussi élégant que dans UWP, c'est-à-dire qu'il n'a pas de propriété VisuaStateManager.Setters. Cela signifie que vous devez utiliser des Storyboards pour définir vos valeurs. |
| DataTemplate implicite | ✔ | ✔ | ✖ | Définissez la propriété DataType du DataTemplate au type correspondant et le modèle est ensuite appliqué automatiquement à toutes les instances de ce type particulier. |
| Binding dans un setter de Style | ✔ | ✔ | ✖ | Tout autre que TemplateBinding n'est pas pris en charge dans un modèle/style au sein de UWP. |
| BasedOn Style par défaut | ✔ | ✔ | ⚡ | BasedOn={StaticResource {x:Type TextBlock} n'est pas pris en charge dans UWP mais fonctionne dans WPF. Au lieu de cela, BasedOn nécessite l'utilisation d'une clé, ce qui pose problème car tous les styles par défaut n'en définissent pas. C'est un exemple spécifique de l'extension de balisage x:Type manquante dans UWP. |
Autre
| Sujet | Avalonia | WPF | UWP | Notes |
|---|---|---|---|---|
| Coercition | ✔ | ✔ | ✖ | La coercition des propriétés de dépendance n'est pas prise en charge dans UWP. |
| Validation des données (Input) | ✔ | ✔ | ✖ | L'ensemble du système de validation des données WPF, y compris les classes/interfaces : ValidationRule (et toutes les implémentations standard), Binding.ValidationRules, IDataErrorInfo, INotifyDataErrorInfo, Binding.ValidatesOnNotifyDataErrors, etc. n'est pas implémenté dans UWP. Cela sera ajouté dans WinUI 3.0, mais l'histoire de son utilisation dans le modèle d'application UWP avec WinUI 3.0 est moins claire. |
| x:TypeArguments | ✔ | ✔ | ✖ | La directive TypeArguments n'est pas implémentée dans UWP, ce qui pose des problèmes avec les génériques. Le manque de cela nécessite quelques solutions de contournement avec des classes et la création d'une classe non générique à utiliser dans XAML à partir d'une classe générique. |
| UIElement.IsVisible / IsVisibleChanged | ✔ | ✔ | ✖ | UWP n'a aucun moyen de suivre quels contrôles sont réellement visibles sur l'affichage. WPF a la propriété UIElement.IsVisible et l'événement IsVisibleChanged. Cela entrave la capacité d'optimiser les contrôles pour les performances. |
| UIElement.Visibility / Visibility.Hidden | ⚡ | ✔ | ⚡ | UWP n'inclut pas la valeur d'énumération Visibility.Hidden utilisée pour UIElement.Visibility. Hidden dans WPF permettait à un contrôle d'être encore utilisé dans la mesure/la mise en page mais d'apparaître invisible lorsqu'il était rendu pour l'affichage. |
| UIElement.Clip | ✔ | ✔ | ⚡ | WPF et UWP ont tous deux des propriétés UIElement.Clip. Cependant, WPF peut prendre n'importe quelle géométrie permettant un découpage non rectangulaire. UWP ne peut utiliser qu'une RectangleGeometry pour le découpage. WPF: public Geometry UIElement.Clip, UWP: public RectangleGeometry UIElement.Clip |
| UIElement.ClipToBounds | ✔ | ✔ | ✖ | Dans WPF, il est possible de découper le contenu enfant aux limites du parent en définissant ClipToBounds sur True. UWP n'a pas du tout cette propriété. La solution de contournement consiste à utiliser UIElement.Clip, qui ne peut effectuer que des découpes rectangulaires. |
| LayoutTransform | ✔ | ✔ | ✖ | La transformation de mise en page est nécessaire pour transformer les éléments avant la mise en page. Cela permet de changer facilement la direction du textbox et de l'insérer ensuite dans un tableau. RenderTransform, qui s'applique après la mise en page, ne redimensionne pas les contrôles parents pour les enfants transformés. |
| VisualBrush / DrawingBrush | ✔ | ✔ | ✖ | VisualBrush n'est pas un pinceau XAML dans UWP. Au lieu de cela, il faut recourir aux pinceaux de composition qui ne sont pas équivalents 1:1. DrawingBrush n'est pas du tout pris en charge dans UWP. |
| Formes supplémentaires : Arrow, Callout, Star, etc | ✔ | ✔ | ✖ | Plusieurs formes présentes dans WPF manquent dans UWP. |
| Ornements | ✔ | ✔ | ✖ | Présentation des ornements |
| Thickness | ✔ | ✔ | ⚡ | La structure Thickness expose des champs pour le Haut, le Bas, la Gauche et la Droite au lieu de propriétés de dépendance comme dans WPF. Cela signifie que vous ne pouvez pas lier ou assigner des ressources à un paramètre d'épaisseur individuel. |
| Size / Rect / Point | ✔ | ✔ | ✔ | Size, Rect et Point sont entièrement pris en charge à la fois dans WPF et UWP. Cependant, UWP utilise des types de float à précision simple pour les propriétés au lieu de double dans WPF. Cela crée une incompatibilité lors du portage de code. |
| ItemsControl.AlternationIndex / ItemsControl.AlternationCount | ✖ | ✔ | ✖ | WPF a un moyen facile de changer le style des éléments dans une liste en utilisant ItemsControl.AlternationIndex et ItemsControl.AlternationCount. Cela permet, par exemple, de changer la couleur de fond d'un élément listé pour les entrées paires/impaire. UWP ne prend pas du tout en charge cela dans aucun des contrôles. La solution partielle dans UWP consiste à créer un nouveau contrôle dérivant de l'implémentation du framework et à remplacer la méthode PrepareContainerForItemOverride(). |
| Curseur personnalisé au runtime | ✔ | ✔ | ✖ | |
| Anti-aliasing pour les sous-pixels | ✔ | ✔ | ✖ | L'anti-aliasing dans UWP, ainsi que le rendu en général, est médiocre par rapport à WPF. On suppose que cela est dû à des raisons de performance sur les appareils mobiles et le web (Silverlight). |
| Types imbriqués dans XAML | ✔ | ✔ | ✖ | L'imbrication de différents types dans XAML n'est généralement pas possible dans UWP. Un code tel que <ListBox.ItemsSource><x:Array><s:string>foo<s/:string><x/:Array></ListBox.ItemsSource> fonctionne dans WPF mais pas dans UWP. |
| Tunnelisation d'événements / Propagation d'événements / Événements routés | ✔ | ✔ | ⚡ | Beaucoup plus d'événements sont simplement directs dans UWP. Certains cas de propagation d'événements tels que ButtonBase.Click vers le parent ne sont pas pris en charge dans UWP. La tunnelisation d'événements, un concept entièrement pris en charge dans WPF, n'est pas du tout supportée dans UWP. |
| Window | ✔ | ✔ | ✖ | Pour certaines bonnes raisons, UWP n'a pas de concept de fenêtre. Cela convient aux appareils mobiles mais peut poser problème pour des applications de bureau pures. Sans fenêtre, il n'y a aucun moyen de contrôler la taille ou la position d'une application. Il y a actuellement des propositions pour ajouter cela dans la transition vers WinUI 3.0. |
Contrôles
Cette section décrit les différences dans les contrôles dans WPF standard et UWP (avec la bibliothèque WinUI 2.x). Elle exclut certaines primitives et formes (Ellipse, Rect, etc.).
| Avalonia | WPF | UWP | Notes |
|---|---|---|---|
| ✖ | ✖ | AppBarButton | |
| ✖ | ✖ | AppBarSeparator | |
| ✖ | ✖ | AppBarToggleButton | |
| AutoCompleteBox | ✖ | AutoSuggestBox | AutoCompleteBox ne prend pas en charge les événements de requête |
| Border | Border | Border | |
| BulletDecorator | BulletDecorator | ✖ | |
| Button | Button | Button | |
| CalendarDatePicker | DatePicker | CalendarDatePicker | Le sélecteur de date UWP est différent du sélecteur de date WPF. Le sélecteur de date WPF est plus proche du CalendarDatePicker UWP en termes de fonctionnalité. |
| Calendar | Calendar | CalendarView | |
| Canvas | Canvas | Canvas | |
| ✖ | ✖ | CaptureElement | |
| CheckBox | CheckBox | CheckBox | |
| ColorPicker | ✖ | ColorPicker | |
| ComboBox | ComboBox | ComboBox | |
| ✖ | ToolBar | CommandBar | |
| ✖ | ✖ | CommandBarFlyout | Introduit pour la première fois dans Windows UI Library |
| ContentControl | ContentControl | ContentControl | |
| ContentPresenter | ✖ | ContentPresenter | |
| DataGrid | DataGrid | ✖ | Disponible pour UWP dans Windows Community Toolkit (bien qu'avec de nombreux bugs) |
| DatePicker | ✖ | DatePicker | Un sélecteur pour choisir une date sans vue de calendrier n'existe pas dans WPF. |
| DatePickerFlyout | ✖ | DatePickerFlyout | |
| DockPanel | DockPanel | ✖ | Disponible pour UWP dans Windows Community Toolkit |
| ✖ | DocumentViewer | ✖ | |
| DropDownButton | ✖ | DropDownButton | Introduit pour la première fois dans Windows UI Library |
| Expander | Expander | ✖ | Disponible pour UWP dans Windows Community Toolkit |
| Carousel | ✖ | FlipView | |
| ✖ | FlowDocumentPageViewer | ✖ | |
| ✖ | FlowDocumentReader | ✖ | |
| ✖ | FlowDocumentScrollViewer | ✖ | |
| Flyout | ✖ | Flyout | |
| ✖ | Frame | Frame | |
| Grid | Grid | Grid | |
| GridSplitter | GridSplitter | ✖ | Disponible pour UWP dans Windows Community Toolkit |
| ✖ | GridView | GridView | |
| ✖ | GroupBox | ✖ | |
| ✖ | ✖ | Hub | |
| ✖ | ✖ | HubSection | |
| HyperlinkButton | ✖ | HyperlinkButton | |
| Image | Image | Image | |
| ✖ | InkCanvas | InkCanvas | |
| ✖ | ✖ | InkToolbar | |
| ItemsControl | ItemsControl | ItemsControl | |
| ItemsPresenter | ItemsPresenter | ItemsPresenter | |
| ItemsRepeater | ✖ | ItemsRepeater | Introduit pour la première fois dans Windows UI Library |
| Label | Label | ✖ | Pour la compatibilité avec Windows Forms |
| ListBox | ListBox | ListBox | |
| ✖ | ListView | ListView | |
| ✖ | ✖ | MapControl | |
| MaskedTextBox | ✖ | ✖ | Disponible pour UWP via TextBoxExtensions dans Windows Community Toolkit |
| ✖ | ✖ | MediaElement | |
| ✖ | ✖ | MediaTransportControls | |
| Menu | Menu | MenuBar | Introduit pour la première fois dans Windows Community Toolkit puis dans Windows UI Library |
| ContextMenu | ContextMenu | MenuFlyout | |
| ✖ | ✖ | NavigationView | |
| NumericUpDown | Panel | NumberBox | NumberBox est disponible dans WinUI 2 / 3 |
| Panel | Panel | ✖ | |
| ✖ | ✖ | ParallaxView | |
| TextBox (PasswordChar) | PasswordBox | PasswordBox | |
| ✖ | ✖ | PersonPicture | |
| TabControl | TabControl | Pivot | |
| TabItem | TabItem | PivotItem | |
| Popup | Popup | Popup | |
| ✖ | PrintDialog | ✖ | |
| ProgressBar | ProgressBar | ProgressBar | |
| ✖ | ✖ | ProgressRing | |
| RefreshContainer | ✖ | PullToRefresh | |
| RadioButton | RadioButton | RadioButton | |
| ✖ | ✖ | RatingControl | |
| Rectangle | Rectangle | Rectangle | |
| ✖ | ✖ | RefreshContainer | Introduit pour la première fois dans Windows UI Library |
| RelativePanel | ✖ | RelativePanel | |
| RepeatButton | RepeatButton | RepeatButton | |
| ✖ | RichTextBox | RichEditBox | |
| ✖ | ✖ | RichTextBlock | |
| ✖ | ✖ | RichTextBlockOverflow | |
| ScrollBar | ScrollBar | ScrollBar | |
| ScrollContentPresenter | ScrollContentPresenter | ScrollContentPresenter | |
| ScrollViewer | ScrollViewer | ScrollViewer | |
| SelectableTextBlock | ✖ | ✖ | Le TextBlock UWP a une propriété IsTextSelectionEnabled |
| ✖ | ✖ | SemanticZoom | |
| Separator | Separator | MenuFlyoutSeparator | |
| Slider | Slider | Slider | |
| SplitButton | ✖ | SplitButton | Introduit pour la première fois dans Windows UI Library |
| SplitView | ✖ | SplitView | |
| StackPanel | StackPanel | StackPanel | |
| ✖ | StatusBar | ✖ | Ce n'est plus une convention UI |
| ✖ | ✖ | SwipeControl | Introduit pour la première fois dans Windows UI Library |
| ✖ | ✖ | TabView | Introduit pour la première fois dans Windows UI Library |
| ✖ | ✖ | TeachingTip | Introduit pour la première fois dans Windows UI Library |
| TextBlock | TextBlock | TextBlock | |
| TextBox | TextBox | TextBox | |
| TimePicker | ✖ | TimePicker | |
| TimePickerFlyout | ✖ | TimePickerFlyout | |
| ToggleButton | ToggleButton | ToggleButton | |
| ToggleSplitButton | ✖ | ToggleSplitButton | Introduit pour la première fois dans Windows UI Library |
| ToggleSwitch | ✖ | ToggleSwitch | |
| ToolTip | ToolTip | ToolTip | |
| TreeView | TreeView | TreeView | |
| ✖ | ✖ | TwoPaneView | Introduit pour la première fois dans Windows UI Library |
| ✖ | ✖ | VariableSizedWrapGrid | |
| UniformGrid | UniformGrid | ✖ | Disponible pour UWP dans Windows Community Toolkit |
| Viewbox | Viewbox | Viewbox | |
| ✖ | ✖ | WebView | |
| WrapPanel | WrapPanel | ✖ | Disponible pour UWP dans Windows Community Toolkit |
| Window | Window | ✖ | Il n'y a pas de concept de fenêtre de niveau supérieur dans UWP |
Particularités
- Plusieurs contrôles UWP ont des problèmes de réentrance. Par exemple, changer l'élément sélectionné pendant un événement SelectionChanged d'un ComboBox n'est généralement pas possible et entraînera un crash. Cela rend la validation directement dans le gestionnaire d'événements presque impossible.
- Les contrôles UWP ne sont généralement pas aussi puissants que leurs homologues WPF. Par exemple, pendant plusieurs années, le ComboBox dans UWP n'était pas modifiable. Le sélecteur de date UWP ne permet également pas de taper une date spécifique.
- UWP ne prend pas en charge la validation des données (entrée). C'est un problème majeur pour les applications de ligne de métier migrantes de WPF vers UWP qui utilisent fortement cette fonctionnalité dans les modèles de vue ou les liaisons.
- Le système de style UWP est suffisamment différent de WPF pour nécessiter des efforts supplémentaires lors du portage. UWP utilise le VisualStateManager au lieu de concepts comme les DataTriggers ou les EventTriggers de WPF. Le style et le modèle sont l'une des principales différences.
- Le balisage XAML ResourceDictionary dans UWP prend en charge beaucoup moins de fonctionnalités que dans WPF.
- UWP semble suivre uniquement la spécification XAML/2006 au lieu de XAML/2009 prise en charge par WPF.
- Plusieurs contrôles UWP sont scellés et de nouveaux contrôles ne peuvent pas en dériver.
- Pour le rendu avancé, UWP dispose de moins de fonctionnalités intégrées. Cela nécessite de revenir plus souvent à Win2D ou à la composition.
- Il existe plusieurs différences de namespaces entre UWP et WPF. Par exemple, WPF a System.Windows.Media.Colors tandis qu'UWP le déplace vers Windows.UI.Colors.
Avalonia XPF - Cross-Platform WPF
Take your WPF apps to macOS and Linux in minutes, not months.