Dot.Blog

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

La continuité dans le changement avec MAUI

Je vous ai parlé des spécificités de MAUI, j’ai parlé aussi de la migration des Xamarin.Forms vers MAUI et j’en reparlerai. Mais il faut se rappeler que beaucoup de choses sont identiques !

Le but de cet article est que vous montrer que certaines implémentations conservent exactement la même structure que celles des Xamarin.Forms ! Parler de migration de kit de compatibilité peut effrayer un peu, c’est vrai. Alors il faut aussi rassurer ! Je vais vous montrer ici quelques constructions classiques Xamarin.Forms et leur équivalent MAUI. Vous verrez que dans bien des cas il s’agit de la même chose. Pas de quoi s’inquiéter donc !

Les Behaviors

Les Behaviors vous permettent d'attacher une fonctionnalité à un élément dans une vue. Cette fonctionnalité peut être réutilisable et nous permet aussi de réaliser facilement des tests unitaires. Prenons un exemple très simple de validation numérique pour un Entry :

Sous Xamarin.Forms

using Xamarin.Forms;
namespace Behaviors
{
    public class NumericValidationBehavior : Behavior
    {
        protected override void OnAttachedTo(Entry entry)
        {
            entry.TextChanged += OnEntryTextChanged;
            base.OnAttachedTo(entry);
        }

        protected override void OnDetachingFrom(Entry entry)
        {
            entry.TextChanged -= OnEntryTextChanged;
            base.OnDetachingFrom(entry);
        }
        void OnEntryTextChanged(object sender, TextChangedEventArgs args)
        {
            bool isValid = double.TryParse(args.NewTextValue, out double result);
            ((Entry)sender).TextColor = isValid ? Color.Default : Color.Red;
        }
    }
}

 

Sous .NET MAUI

using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
 
namespace Behaviors
{
    public class NumericValidationBehavior : Behavior
    {
        protected override void OnAttachedTo(Entry entry)
        {
            entry.TextChanged += OnEntryTextChanged;
            base.OnAttachedTo(entry);
        }
 
        protected override void OnDetachingFrom(Entry entry)
        {
            entry.TextChanged -= OnEntryTextChanged;
            base.OnDetachingFrom(entry);
        }

         void OnEntryTextChanged(object sender, TextChangedEventArgs args)
        {
            bool isValid = double.TryParse(args.NewTextValue, out double result);
            ((Entry)sender).TextColor = isValid ? Colors.Black : Colors.Red;
        }
    }
}

 

Quelle différence ? Cherchez-bien ! … Aucune en dehors des namespaces !

Les Triggers

Un déclencheur, vous permet d'ajouter des actions aux contrôles graphiques à partir du XAML, vous permettant de modifier l'apparence de vos contrôles lorsqu'une action spécifique se produit. Ces actions peuvent être : Lorsqu'un événement se produit ou lorsqu'une propriété d’un contrôle est modifié.  Ici aussi prenons un exemple très simple d’un champ obligatoire :

Xamarin.Forms

<Entry

    x:Name="Entry"

    Text=""

    Placeholder="Required field" />

<!-- Referenced below in DataTrigger-->

<Button

    x:Name="Button"

    Text="Save"

    FontSize="Large"

    HorizontalOptions="Center">

    <Button.Triggers>

        <DataTrigger

            TargetType="Button"

            Binding="{Binding Source={x:Reference Entry},

                            Path=Text.Length}"

            Value="0">

            <Setter Property="IsEnabled" Value="False" />

        </DataTrigger>

    </Button.Triggers>

</Button>

 

Sous .NET MAUI

<Entry

    x:Name="Entry"

    Text=""

    Placeholder="Required field" />

<!-- Referenced below in DataTrigger-->

<Button

    x:Name="Button"

    Text="Save"

    FontSize="Large"

    HorizontalOptions="Center">

    <Button.Triggers>

        <DataTrigger

            TargetType="Button"

            Binding="{Binding Source={x:Reference Entry},

                            Path=Text.Length}"

            Value="0">

            <Setter Property="IsEnabled" Value="False" />

        </DataTrigger>

    </Button.Triggers>

</Button>

 

Cela se passe de commentaire, même code…

Les convertisseurs

Les convertisseurs permettent de transmettre des données avec des valeurs différentes ! Ils servent souvent à adapter des données du ViewModel ou du Model pour les contrôles de la Vue.

Encore une fois, un exemple redoutablement simple, un convertisseur numérique vers booléen à double sens de fonctionnement :

Sous Xamarin.Forms

using System;
using System.Globalization;
using Xamarin.Forms;
 
namespace Converters
{
    public class IntToBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (int)value != 0;
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (bool)value ? 1 : 0;
        }
    }
}

 

Sous .NET MAUI

using Microsoft.Maui.Controls;
using System;
using System.Globalization;
 
namespace Converters
{
    public class IntToBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (int)value != 0;
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (bool)value ? 1 : 0;
        }
    }
}

 

Encore une fois en dehors des namespaces, le même code est réutilisé sans modification !

Conclusion

Certes le passage d’une App entière Xamarin.Forms vers MAUI peut réclamer un certain travail qui s’assimile à celui d’une migration. Mais rien ne sert de se faire inutilement peur non plus ! Enormément de structures, de codes, sont réutilisables directement en changeant juste les usings en début de page… Donc ne vous inquiétez pas trop, il ne s’agit pas de migrer du VB6 old school (dernière version en 1998) vers WPF en C# ! On peut le faire, je l’ai déjà fait pour de gros projets, mais là cela n’a rien à voir. Il faut juste faire attention à des tas de petits détails comme pour toute migration et cela se passe encore mieux si on est accompagné par un expert. Mais les réécritures de code ne sont pas énormes grâce à une compatibilité presque parfaite comme on vient de le voir !

Stay tuned !

Faites des heureux, PARTAGEZ l'article !