Dot.Blog

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

Réutiliser les renderers Xamarin.Forms dans MAUI

Comment réutiliser les renderers Xamarin.Forms dans une application MAUI sachant que leur nature a totalement changé ? Je vais vous montrer une astuce très simple !

Le pack de compatibilité

Je vous ai présenté (et même dans un podcast devdevdev.net) ce qu’était le pack de compatibilité. Pour ceux qui n’ont pas suivi, il s’agit d’une bibliothèque permettant de reprendre du code Xamarin.Forms dans MAUI sans rien y changer tout en étant sûr que cela tourne sous MAUI. Il faut le voir comme une étape de la migration de code vers MAUI car, à termes, il faut adopter les bibliothèques spécifiques MAUI seules appelées à évoluer et offrant d’ors et déjà des améliorations propres à MAUI. Mais le pack de compatibilité est un atout intéressant évitant un long effet tunnel lors d’une migration de code vers MAUI depuis Xamarin.Forms. C’est lui que nous utiliserons ici pour récupérer le travail investi dans les renderers spécifiques des Xamarin.Forms et ne rien perdre de ce travail (en adaptant de l’adapter réellement à MAUI).

Les Renderers de Xamarin.Forms

Les interfaces utilisateur Xamarin.Forms sont créées à l'aide de contrôles natifs de la plateforme cible, ce qui permet aux applications Xamarin.Forms de conserver l'apparence appropriée pour chaque plateforme. Les rendus personnalisés permettent aux développeurs d'utiliser ce processus pour personnaliser l'apparence et le comportement des contrôles Xamarin.Forms sur chaque plateforme.

Voici un exemple ultra simplifié d’un renderer personnalisé Xamarin.Forms pour un contrôle de type Entry :


using Xamarin.Forms;
namespace Renderers
{
    public class CustomEntry : Entry
    {
    }
}


L’implémentation Android :


using Android.Content;
using Renderers;
using Renderers.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Renderers.Droid.Renderers
{
    public class CustomEntryRenderer : EntryRenderer
    {
        public CustomEntryRenderer(Context context) : base(context)
        {
        }
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
            {
                Control.SetBackgroundColor(global::Android.Graphics.Color.LightGreen);
            }
        }
    }
}


Comme on peut le voir, on ne modifie ici que la couleur de fond du champ natif. Quelque chose de vraiment simple, mais suffisant pour les besoins de ce papier et apprendre à réutiliser les Renderers sans changer leur code.

Réutiliser le moteur de rendu

Le moteur de rendu dans .NET MAUI utilise exactement le même code :


using Android.Content;
using Compatibility;
using Compatibility.Droid.Renderers;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.Compatibility;
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Compatibility.Droid.Renderers
{
    public class CustomEntryRenderer : EntryRenderer
    {
        public CustomEntryRenderer(Context context) : base(context)
        {
        }
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
            {
                Control.SetBackgroundColor(global::Android.Graphics.Color.LightGreen);
            }
        }
    }
}


Les seuls changements consistent à remplacer certains espaces de noms pour utiliser Microsoft.Maui.Controls.Compatibility .

Et est-ce que tout est prêt ?

Pas exactement, au lieu d'utiliser l’Assembly Scanning, .NET MAUI utilise la classe Startup pour effectuer des tâches telles que l'enregistrement de Handlers ou de Renderers. C’est une des améliorations qui permet d’accélérer le chargement des Apps (au lieu de balayer tous les assemblies par réflexion, ce qui est lent, les renderers sont directement enregistrés par le développeur dans le moteur de DI et ainsi immédiatement disponibles sans scanning coûteux).


public class Startup : IStartup
{
    public void Configure(IAppHostBuilder appBuilder)
    {
        appBuilder
            .UseMauiApp<App>()
            .ConfigureMauiHandlers(handlers =>
            {
#if __ANDROID__
                handlers.AddCompatibilityRenderer(typeof(CustomEntry), typeof(Droid.Renderers.CustomEntryRenderer));
#endif
            });
    }
}


En ajoutant l’enregistrement du code du renderer Xamarin.Forms via le pack de compatibilité les Entry MAUI sous Android (c’est l’exemple) seront personnalisés comme dans l’App originale et sans changement de code sauf quelques namespaces !

Conclusion

Le pack de compatibilité n’est pas qu’un artifice pour simplifier le portage intermédiaire de code Xamarin.Forms vers MAUI, c’est vraiment un outil puissant permettant d’envisager plus sereinement la migration des Apps, même dans leurs spécificités les plus tortueuses comme les Renderers et malgré les grandes différences avec MAUI. Sans éclat, sans tambour ni trompette, Microsoft nous propose des solutions concrètes très puissantes qui facilitent le portage des Apps Xamarin.Forms. Et toutes en auront besoin… d’une part car toute App doit être redéveloppée au bout de 3 à 5 ans, et d’autre part parce que Xamarin.Forms a cédé sa place à MAUI et que plus vite les Apps seront migrées vers ce nouvel environnement plus vite elles pourront bénéficier de toutes les améliorations et allonger considérablement leur temps de vie technique.

Si vous avez des questions, si vous rencontrez des difficultés ou voulez savoir quelles difficultés le portage spécifique de votre code pourrait soulever, n’oubliez pas que votre serviteur offre son expertise sous forme d’audit, de conseil et même de développement, contactez-moi !

Stay tuned !



Faites des heureux, partagez l'article !
blog comments powered by Disqus