Dot.Blog

C#, XAML, WinUI, WPF, Android, MAUI, IoT, IA, ChatGPT, Prompt Engineering

Les Handlers MAUI

MAUI a introduit un nouveau procédé pour personnaliser les contrôles natifs : les « handlers » qui remplacent les « renderers ». Pourquoi un tel changement et quels avantages et pourquoi cela reste-t-il encore un peu mystérieux ?

Qu'est-ce qu'un handler .NET MAUI ?

Un handler .NET MAUI (un gestionnaire en français) est un concept architectural utilisé par .NET MAUI pour mapper les contrôles multiplateformes à leur implémentation native. Les handlers sont utilisés à la place des moteurs de rendu (renderers) de Xamarin.Forms dans .NET MAUI car ils offrent plusieurs avantages. Rapidité, simplicité d’utilisation, facilité de personnalisation, etc… Bien qu'introduits depuis un moment, les Handlers restent souvent mal compris et donc pas assez utilisés. Il est vrai qu'on peut faire tant de choses en restant en MAUI pure qu'il faut avoir de réels besoins motivés sérieusement pour se lancer dans les bricolages liés à chaque plateforme. Mais cela fait partie du savoir-faire à intégrer quand on développe en cross-plateforme.
 
Pour mieux comprendre il est important de définir d'autres termes. Cela sera utile pour tous ceux qui souhaitent une introduction aux handlers .NET MAUI mais qui ne sont pas passés par les Xamarin.Forms pour venir à MAUI.Un moteur de rendu Xamarin Forms (un renderer) est un concept architectural utilisé sur chaque plate-forme ciblée par Xamarin Forms pour créer le contrôle approprié au moment de l'affichage. C'est pourquoi les contrôles sont natifs sur chaque plateforme, les contrôles Xamarin.Forms comme ceux de MAUI ne sont qu'on façade pour paramétrer les véritables contrôles de la plateforme qui seront instancies.
Notez que chaque contrôle dans Xamarin Forms a son propre moteur de rendu. Sachant que MAUI fonctionne d'une façon assez similaire (mais c'est le sujet du jour on va donc y revenir) on comprend la difficulté de proposer un designer visuel... les contrôles Xamarin.Forms ou MAUI n'existent pas ! Ce sont des fantômes utilisés pour paramétrer l'UI mais ce ne sont pas les contrôles qui seront instanciés sur chaque plateforme.
Cet avantage se retourne donc en difficulté tant il est vrai que travailler en 2024 sans designer visuel que même VB ou Delphi proposaient il y a plus de 20 ans semble un retour en arrière incompréhensible.
En fait si, ça se comprend si vous pigez ce concept de contrôles fantomatiques remplacés à l'exécution par des contrôles natifs...Un mappeur MAUI, quant à lui, est un dictionnaire à l'intérieur d'un handler servant à mapper les API multiplateformes sur les API natives.Remarque : .NET MAUI n'utilise pas les moteurs de rendu. Mais il dispose d'une couche de compatibilité qui vous permet d'utiliser vos anciens moteurs de rendu Xamarin Forms sans analyse d'assemblage (XF obligeait à balayer tous les assemblies pour détecter les handlers, pas MAUI) ce qui est un gain.
Mais bon, il ne faut pas que cela dure de trop, pensez à migrer rapidement ce code ancien !

Pourquoi passer des Renderers aux Handlers ? 

Les handlers sont l'une des fonctionnalités les plus attrayantes que .NET MAUI nous apporte. Si vous êtes un ancien développeur Xamarin Forms, vous devriez rapidement comprendre pourquoi après les avoir utilisés. Ils rendent la vie beaucoup plus facile, lorsque nous voulons personnaliser les contrôles, et bien plus encore. Voici quelques avantages des handlers : 
  • Performances améliorées : Avec les renderers la réflexion et l'analyse des assemblages sont utilisées pour lister et enregistrer les rendus pour tous les contrôles. Ce processus est lent et a un impact négatif sur les performances. De leur côté les handlers MAUI n'ont pas besoin de scanner les assemblages.
  • Code plus maintenable : Les handlers sont faciles à implémenter et à utiliser via le modèle de générateur d'hôte de .NET MAUI, ils peuvent facilement être ajoutés à un type de contrôle spécifique ou à chaque contrôle utilisé dans votre application.
  • Il est plus facile d'accéder et de modifier directement les contrôles natifs . Avec les moteurs de rendu Xamarin Forms on devait écrire beaucoup de code pour modifier les contrôles natifs sous-jacents. Les handlers rendent cela beaucoup plus facile.
  • Les handlers en eux-mêmes sont faciles à implémenter par rapport à tout le code redondant requis pour modifier un moteur de rendu (renderer).
  • Les contrôles natifs de chaque handlers ne sont pas encapsulés (Fast Renderers) dans une sorte de conteneur comme cela se faisait dans le passé.
 Il est bien entendu possible d’aller plus loin dans les nombreux avantages des handlers mais ceux présentés ici sont déjà bien suffisants pour justifier l’abandon des renderers Xamarin.Forms.Comprendre l'architecture du gestionnaire .NET MAUI 
La documentation de .NET MAUI commence à être au point, ce qui n'était pas le cas il y en encore pas si longtemps, et vous pouvez bien entendu vous y référer en complément, c’est toujours une bonne idée. Mais l’autre façon la plus fiable d’accéder à toute l’information sur un code… c’est de l’étudier ! N’oubliez pas que le code de MAUI est ouvert et accessible sur GitHub. 

Pour comprendre les handlers il est important de noter que les contrôles de .NET MAUI ont chacun une représentation sous forme d'interface, qui est une abstraction du contrôle natif concerné. Ces interfaces sont dérivées de l' interface IView . Chaque handler utilise ces interfaces des contrôles et ne touche le contrôle sous-jacent qu’uniquement au niveau de la plateforme lorsqu’il mappe les propriétés.
Prenons le Label comme exemple. Voici l' interface ILabel implémentée par Label MAUI.
 
 
Le code de l'interface ci-dessus et d'autres interfaces pour les contrôles disponibles dans .NET MAUI peuvent être trouvés ici . Les handlers fournissent désormais une couche d'abstraction pour ces contrôles. Le schéma ci-dessous, extrait de la documentations Microsoft, met très bien en évidence cette architecture :
 
 
Comme mentionné ci-dessus, chaque contrôle .NET MAUI hérite de l'interface appropriée. La classe qui implémente cette interface contient les propriétés pouvant être liées et les mappeurs si nécessaire.
Pour notre contrôle Label, vous pouvez trouver les classes partielles implémentant l'interface ILabel ici et ici aussi .
 
NOTE : Nous appellerons les champs qui implémentent ces interfaces (dérivant de l'interface IView) « Vues Virtuelles » (ce que j'ai appelé plus parfois des contrôles fantôme).
 
Le handler est ensuite chargé de prendre l'implémentation de ILabel, de créer le contrôle natif sous-jacent et de mapper ses propriétés à celles de la vue virtuelle. Voilà, une fois que vous avez compris cela les handlers deviendront vite vos amis ! Chaque Handler .NET MAUI est dérivé de la classe abstraite ViewHandler . Comme vous pouvez le voir dans l'image ci-dessous, cette classe précise que lors du ciblage des frameworks de chaque plate-forme, le TNativeView doit être un dérivé de la classe NativeView, et lors du ciblage d'un projet standard .Net, cela peut être n'importe quelle classe. Vous pouvez voir la définition d'autres méthodes abstraites comme "CreateNativeView" en parcourant le code source ici .