Cycle de vie de l’application WPF et Xamarin.Forms

Xamarin.Forms utilise de nombreux conseils de conception à partir des frameworks XAML qui l’ont précédé, en particulier WPF. Toutefois, à d’autres égards, il s’écarte considérablement, ce qui peut être un point collant pour les personnes qui tentent de migrer. Ce document tente d’identifier certains de ces problèmes et de fournir des conseils dans la cas où cela est possible pour relier les connaissances WPF à Xamarin.Forms.

Cycle de vie d’application

Le cycle de vie de l’application entre WPF et Xamarin.Forms est similaire. Les deux démarrent dans du code externe (plateforme) et lancent l’interface utilisateur via un appel de méthode. La différence est que Xamarin.Forms démarre toujours dans un assembly spécifique à la plateforme qui initialise et crée ensuite l’interface utilisateur de l’application.

WPF

  • Main method > App > MainWindow

Notes

Par Main défaut, la méthode est générée automatiquement et n’est pas visible dans le code.

Xamarin.Forms

  • iOS : Main method > AppDelegate > App > ContentPage
  • AndroidMainActivity > App > ContentPage
  • UWPMain method > App(UWP) > MainPage(UWP) > App > ContentPage

Classe Application

WPF et Xamarin.Forms ont une Application classe qui est créée en tant que singleton. Dans la plupart des cas, les applications dérivent de cette classe pour fournir une application personnalisée, bien que cela ne soit pas strictement requis dans WPF. Les deux exposent une Application.Current propriété pour localiser le singleton créé.

Propriétés globales + persistance

WPF et Xamarin.Forms disposent d’un Application.Properties dictionnaire dans lequel vous pouvez stocker des objets globaux au niveau de l’application qui sont accessibles n’importe où dans l’application. La principale différence est que Xamarin.Forms conserve tous les types primitifs stockés dans la collection lorsque l’application est suspendue, et les recharge quand elle est relancée. WPF ne prend pas automatiquement en charge ce comportement : à la place, la plupart des développeurs s’appuient sur le stockage isolé ou utilisent la prise en Settings charge intégrée.

Définition des pages et de l’arborescence visuelle

WPF utilise comme Window élément racine pour tout élément visuel de niveau supérieur. Cela définit un HWND dans le monde Windows pour afficher des informations. Vous pouvez créer et afficher autant de fenêtres simultanément que vous le souhaitez dans WPF.

Dans Xamarin.Forms, le visuel de niveau supérieur est toujours défini par la plateforme . Par exemple, sur iOS, il s’agit d’un UIWindow. Xamarin.Forms restitue son contenu dans ces représentations de plateforme natives à l’aide d’une Page classe . Chaque Page dans Xamarin.Forms représente une « page » unique dans l’application, où une seule est visible à la fois.

Les fichiers WPF Window et Xamarin.Forms Page incluent une Title propriété pour influencer le titre affiché, et ont tous deux une Icon propriété pour afficher une icône spécifique pour la page (Notez que le titre et l’icône ne sont pas toujours visibles dans Xamarin.Forms). En outre, vous pouvez modifier les propriétés visuelles courantes sur les deux, telles que la couleur d’arrière-plan ou l’image.

Il est techniquement possible d’effectuer un rendu vers deux vues de plateforme distinctes (par exemple, définir deux UIWindow objets et faire en sorte que le second s’affiche sur un affichage externe ou AirPlay), il nécessite du code spécifique à la plateforme pour ce faire et n’est pas une fonctionnalité directement prise en charge par Xamarin.Forms lui-même.

Les vues

La hiérarchie visuelle pour les deux frameworks est similaire. WPF est un peu plus profond en raison de sa prise en charge des documents WYSIWYG.

WPF

DependencyObject - base class for all bindable things
   Visual - rendering mechanics
      UIElement - common events + interactions
         FrameworkElement - adds layout
            Shape - 2D graphics
            Control - interactive controls

Xamarin.Forms

BindableObject - base class for all bindable things
   Element - basic parent/child support + resources + effects
      VisualElement - adds visual rendering properties (color, fonts, transforms, etc.)
         View - layout + gesture support

Cycle de vie de l’affichage

Xamarin.Forms est principalement axé sur les scénarios mobiles. Par conséquent, les applications sont activées, suspendues et réactivées à mesure que l’utilisateur interagit avec elles. Cela est similaire à un clic à partir de dans Window une application WPF et il existe un ensemble de méthodes et d’événements correspondants que vous pouvez remplacer ou vous connecter à pour surveiller ce comportement.

Objectif WPF, méthode Xamarin.Forms, méthode
Activation initiale ctor + Window.OnLoaded ctor + Page.OnStart
Montré Window.IsVisibleChanged Page.Apparaissant
Hidden Window.IsVisibleChanged Page.Disappearing
Suspendre/Perdre le focus Window.OnDeactivated Page.OnSleep
Activé/Focus activé Window.OnActivated Page.OnResume
Fermés Window.OnClosing + Window.OnClosed n/a

Les deux prennent également en charge le masquage/affichage des contrôles enfants. Dans WPF, il s’agit d’une propriété IsVisible à trois états (visible, masqué et réduit). Dans Xamarin.Forms, elle est simplement visible ou masquée via la IsVisible propriété .

Layout

La mise en page se produit dans les mêmes 2 passes (Mesure/Arranger) que dans WPF. Vous pouvez vous connecter à la mise en page en remplaçant les méthodes suivantes dans la classe Xamarin.Forms Page :

Méthode Objectif
OnChildMeasureInvalidated La taille préférée d’un enfant a changé.
OnSizeAllocated Une largeur/hauteur a été attribuée à la page.
Événement LayoutChanged La disposition/la taille de la page a changé.

Il n’existe aucun événement de disposition globale appelé aujourd’hui, ni d’événement global CompositionTarget.Rendering comme dans WPF.

Propriétés de disposition courantes

WPF et Xamarin.Forms prennent tous deux en charge Margin le contrôle de l’espacement autour d’un élément et Padding l’espacement à l’intérieur d’un élément. En outre, la plupart des vues de disposition Xamarin.Forms ont des propriétés pour contrôler l’espacement (par exemple, ligne ou colonne).

En outre, la plupart des éléments ont des propriétés qui influencent leur positionnement dans le conteneur parent :

WPF Xamarin.Forms Objectif
Horizontalalignment HorizontalOptions Options Gauche/Centre/Droite/Étirement
Verticalalignment VerticalOptions Options Top/Center/Bottom/Stretch

Notes

L’interprétation réelle de ces propriétés dépend du conteneur parent.

Affichages de disposition

WPF et Xamarin.Forms utilisent tous deux des contrôles de disposition pour positionner les éléments enfants. Dans la plupart des cas, ceux-ci sont très proches les uns des autres en termes de fonctionnalités.

WPF Xamarin.Forms Style de disposition
StackPanel StackLayout Empilement infini de gauche à droite ou de haut en bas
Grille Grille Format tabulaire (lignes et colonnes)
DockPanel n/a Ancrer aux bords de la fenêtre
Canevas AbsoluteLayout Positionnement des pixels/coordonnées
WrapPanel n/a Pile de habillage
n/a RelativeLayout Positionnement relatif basé sur des règles

Notes

Xamarin.Forms ne prend pas en charge .GridSplitter

Les deux plateformes utilisent des propriétés attachées pour affiner les enfants.

Rendu

Les mécanismes de rendu pour WPF et Xamarin.Forms sont radicalement différents. Dans WPF, les contrôles que vous créez affichent directement le contenu en pixels à l’écran. WPF conserve deux graphiques d’objets (arborescences) pour représenter cela : l’arborescence logique représente les contrôles tels que définis dans le code ou XAML, et l’arborescence visuelle représente le rendu réel qui se produit à l’écran, qui est effectué soit directement par l’élément visuel (par le biais d’une méthode de dessin virtuel), soit par le biais d’une définition XAML ControlTemplate qui peut être remplacée ou personnalisée. En règle générale, l’arborescence visuelle est plus complexe, car elle inclut des éléments tels que des bordures autour des contrôles, des étiquettes pour le contenu implicite, etc. WPF inclut un ensemble d’API (LogicalTreeHelper et VisualTreeHelper) pour examiner ces deux graphiques d’objets.

Dans Xamarin.Forms, les contrôles que vous définissez dans un Page ne sont vraiment que de simples objets de données. Ils sont similaires à la représentation d’arborescence logique, mais ne rendent jamais le contenu par eux-mêmes. Au lieu de cela, il s’agit du modèle de données qui influence le rendu des éléments. Le rendu réel est effectué par un ensemble distinct de convertisseurs visuels qui sont mappés à chaque type de contrôle. Ces convertisseurs sont inscrits dans chacun des projets spécifiques à la plateforme par des assemblys Xamarin.Forms spécifiques à la plateforme. Vous pouvez voir une liste ici. En plus de remplacer ou d’étendre le convertisseur, Xamarin.Forms prend également en charge les effets qui peuvent être utilisés pour influencer le rendu natif sur une base par plateforme.

Arborescence logique/visuelle

Il n’existe aucune API exposée pour parcourir l’arborescence logique dans Xamarin.Forms, mais vous pouvez utiliser Reflection pour obtenir les mêmes informations. Par exemple, voici une méthode qui peut énumérer des enfants logiques avec réflexion.

Graphiques

Xamarin.Forms inclut un système graphique pour dessiner des primitives, appelé Formes. Pour plus d’informations sur les formes, consultez Xamarin.Forms Shapes. En outre, vous pouvez inclure des bibliothèques tierces telles que SkiaSharp pour obtenir un dessin 2D multiplateforme.

Ressources

WPF et Xamarin.Forms ont tous deux le concept de ressources et de dictionnaires de ressources. Vous pouvez placer n’importe quel type d’objet dans un ResourceDictionary avec une clé, puis rechercher des {StaticResource} éléments qui ne changeront pas ou {DynamicResource} des éléments qui peuvent changer dans le dictionnaire au moment de l’exécution. L’utilisation et la mécanique sont identiques avec une différence : Xamarin.Forms exige que vous définissiez le ResourceDictionary à affecter à la Resources propriété, tandis que WPF en précrée une et l’affecte pour vous.

Par exemple, consultez la définition ci-dessous :

WPF

<Window.Resources>
   <Color x:Key="redColor">#ff0000</Color>
   ...
</Window.Resources>

Xamarin.Forms

<ContentPage.Resources>
   <ResourceDictionary>
      <Color x:Key="redColor">#ff0000</Color>
      ...
   </ResourceDictionary>
</ContentPage.Resources>

Si vous ne définissez pas le ResourceDictionary, une erreur d’exécution est générée.

Styles

Les styles sont également entièrement pris en charge dans Xamarin.Forms et peuvent être utilisés pour thèmer les éléments Xamarin.Forms qui composent l’interface utilisateur. Ils prennent en charge les déclencheurs (propriété, événement et données), l’héritage via BasedOnet les recherches de ressources pour les valeurs. Les styles sont appliqués aux éléments de manière explicite par le biais de la Style propriété ou implicitement en ne fournissant pas de clé de ressource, tout comme WPF.

Styles d’appareils

WPF a un ensemble de propriétés prédéfinies (stockées en tant que valeurs statiques sur un ensemble de classes statiques telles que SystemColors) qui dictent les couleurs système, les polices et les métriques sous la forme de valeurs et de clés de ressources. Xamarin.Forms est similaire, mais définit un ensemble de styles d’appareil pour représenter les mêmes éléments. Ces styles sont fournis par l’infrastructure et définis sur des valeurs basées sur l’environnement d’exécution (par exemple, l’accessibilité).

WPF

<Label Text="Title" Foreground="{DynamicResource {x:Static SystemColors.DesktopBrushKey}}" />

Xamarin.Forms

<Label Text="Title" Style="{DynamicResource TitleStyle}" />