Dot.Blog

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

MAUI : Ecrire du XAML personnalité par plateforme et idiome

Le développement multiplateforme est attrayant en théorie : coder une seule fois et déployer sur divers systèmes depuis une base de code unique. Toutefois, en pratique, cela s'avère complexe, surtout parce que chaque plateforme a ses propres fonctionnalités et API qui exigent souvent une attention particulière.

Les différences entre les plateformes ne concernent pas uniquement les fonctionnalités, mais aussi l'apparence de l'interface utilisateur. Par exemple, vous pourriez vouloir ajuster les marges supérieures ou utiliser des icônes spécifiques à chaque plateforme. Heureusement, depuis l'avènement de Xamarin.Forms et de MAUI, la gestion de ces aspects est devenue relativement aisée, avec plusieurs méthodes disponibles pour personnaliser l'interface, y compris la modification des contrôles par le biais de gestionnaires et d'extensions de balisage.

Néanmoins, il y a des situations exceptionnelles où une personnalisation détaillée dans un fichier XAML unique ne suffit pas. Que faire si vous avez besoin que des sections complètes d'une page varient considérablement en fonction de la plateforme ou du type d'appareil ? La solution est simple et cela est parfaitement faisable avec MAUI.

Je vais explorer différentes méthodes pour incorporer des fichiers XAML spécifiques à une plateforme ou à un type d'appareil dans votre application. L'une des options est d'employer le multi-ciblage, une pratique bien ancrée dans MAUI grâce aux projets de type "SDK" ou "projet unique". Toutefois, il est crucial de souligner que le multi-ciblage en .NET ne permet pas encore la compilation conditionnelle ni l'exclusion de fichiers XAML selon la plateforme visée. Par conséquent, je vais vous exposer des alternatives éprouvées.

Approches en Code-Behind

Étant donné que cet article concerne XAML, commençons par une mise en page simple. Ici, nous avons un VerticalStackLayout et un x:Name est défini afin que nous puissions manipuler son contenu en y accédant via l'identifiant VerticalLayout dans le code-behind.

<Grid RowDefinitions="*,4*">
  <VerticalStackLayout
    Grid.Row="0"
    x:Name="VerticalLayout" />
</Grid>

Décision au Moment de l'Exécution

La manière la plus simple d'afficher des vues spécifiques à une plateforme est de faire les appels appropriés dans le code-behind en fonction de la plateforme d'exécution actuelle :

if (DeviceInfo.Platform == DevicePlatform.Android)
{
    VerticalLayout.Add(new Android.ViewAndroid());
}
else if (DeviceInfo.Platform == DevicePlatform.iOS)
{
    VerticalLayout.Add(new iOS.ViewiOS());
}

Inconvénient de cette Approche

L'inconvénient de cette méthode est que le code résultant sera disponible sur toutes les plateformes cibles. Cela signifie que même si une vue est spécifique à Android, le code pour cette vue sera toujours inclus dans le package de l'application pour toutes les autres plateformes, ce qui peut entraîner une augmentation de la taille du package et une complexité accrue lors de la maintenance du code. Mais le plus gênant est que la prise de décision se trouve dans le code-behind alors qu'il pourra (devra ?) être dans un ViewModel mais que ce dernier ne peut pas manipuler des classes d'UI. C'est assez embêtant et si un bout de code-behind exemple semble faire le job, en réalité se mettre en conformité avec MVVM compliquera beaucoup les choses si la décision vient du ViewModel (s'il s'agit juste d'UI, le code-behind fait parfaitement l'affaire, c'est donc une question de contexte et ce sur quoi la décision de fournir un XAML ou un autre se base).

Compilation Conditionnelle

Une approche alternative et légèrement meilleure par rapport à la décision au moment de l'exécution consiste à utiliser la compilation conditionnelle :

#if ANDROID
    VerticalLayout.Add(new Android.ViewAndroid());
#elif IOS
    VerticalLayout.Add(new iOS.ViewiOS());
#endif

Avantage de cette Approche

L'avantage ici est que seuls les appels appropriés se retrouvent dans le code de l'application compilée pour chaque plateforme cible, éliminant ainsi la nécessité de prendre une décision au moment de l'exécution. Mais nous sommes loin de la perfection.

Approche Uniquement en XAML

Il est également possible d'afficher uniquement les parties pertinentes de l'interface utilisateur en fonction de la plateforme d'exécution actuelle en utilisant uniquement du XAML, sans code C#, en tirant parti de <OnPlatform>, c'est ma méthode préférée (les problématiques d'UI restent côté UI) :

<Grid RowDefinitions="*,4*">
  <ContentView
    Grid.Row="1"
    Padding="20">
    <OnPlatform x:TypeArguments="View">
      <On Platform="Android">
        <android:ImageViewAndroid />
      </On>
      <On Platform="iOS">
        <iOs:ImageViewiOS />
      </On>
    </OnPlatform>
  </ContentView>
</Grid>

Ici, nous avons un ContentView qui sert de conteneur et nous contrôlons son contenu en utilisant la classe <OnPlatform> et en fournissant différentes vues pour chaque plateforme. Il est important d'inclure l'attribut x:TypeArguments="View" car nous devons indiquer à <OnPlatform> quel est le type de retour, étant donné que la classe ContentView n'accepte que des instances de View comme contenu. C'est vraiment aussi simple que cela !

A noter
Ceci est équivalent à l'approche de décision au moment de l'exécution dans le code-behind, ce qui signifie que toutes les vues de toutes les plateformes seront incluses dans le bundle de l'application. L'utilisation de <OnPlatform> avec des vues secondaires insérées évite le code conditionnel (toujours difficile à tracer et à lire) et même le code C# tout court, laissant à l'UI et son langage se charger de l'UI.

Il est également possible d'utiliser <OnIdiom> pour fournir différentes vues en fonction du type d'appareil (par exemple, tablette, téléphone, ordinateur de bureau) :

<Grid RowDefinitions="*,4*">
  <ContentView
    Grid.Row="1"
    Padding="20">
    <OnIdiom x:TypeArguments="View">
      <On Idiom="Tablet">
        <tablet:TabletView />
      </On>
      <On Idiom="Phone">
        <phone:PhoneView />
      </On>
    </OnIdiom>
  </ContentView>
</Grid>

Imperfections à considérer

Gardez à l'esprit qu'en raison de la nature de la mise en œuvre des approches ci-dessus et du fait que le multi-ciblage n'est actuellement pas pris en charge pour le XAML, seule la partie en code-behind est soumise à la compilation conditionnelle. Cela signifie que tout le code XAML de votre projet d'application sera expédié à toutes les plateformes cibles, y compris le XAML inutilisé qui est spécifique à d'autres plateformes cibles (ou types d'appareils). 

Conclusion

Comme nous l'avons vu, il est en réalité assez facile d'avoir du XAML spécifique à chaque plateforme (ou appareil) dans les applications MAUI en utilisant des décisions au moment de l'exécution (soit en C# soit en XAML) ou la compilation conditionnelle.

Bien qu'il ne soit pas possible (encore) d'utiliser la compilation conditionnelle pour XAML ou même le multi-ciblage basé sur le nom de fichier et de dossier pour les fichiers XAML, les approches présentées peuvent vous aider à améliorer l'expérience utilisateur de votre application multiplateforme en fournissant des vues spécifiques à chaque plateforme ou type de device avec facilité. 

Il faut rappeler malgré tout que si la personnalisation d'une marge, d'un contrôle, au sein d'une page XAML est assez fréquent, l'utilisation de pages totalement spécifiques à chaque plateforme est assez rare. Si jamais il en est autrement pour une App donnée et qu'une majorité de pages est concernée, alors autant concevoir autant d'Apps que de plateformes, même avec MAUI et en utilisant une base de code commune (DLL MAUI par exemple).

Un jour peut-être Microsoft implémentera le multi-ciblage pour les fichiers XAML, cela sera certainement une bonne nouvelle, au moins pour la cohérence de MAUI, mais avouons-le, cela ne sera pas vécu comme une révolution que tout le monde attendait. Si cela n'a pas été déjà fait, on en tient là peut-être la raison…

Stay Tuned !

Le Guide Complet de.NET MAUI ! Lien direct Amazon : https://amzn.eu/d/95wBULD

Près de 500 pages dédiées à l'univers .NET MAUI !

Existe aussi en version Kindle à prix réduit !

Faites des heureux, PARTAGEZ l'article !