Dévelopement

Xamarin.Forms : “Visual” sort du stade expérimental

Dot.Blog - jeu, 07/03/2019 - 20:17

Visual est une nouvelle feature des Xamarin.Forms qui sort de la phase expérimentale pour devenir officielle dans la version 3.6…

Visual ?

Cette nouvelle feature permet de supporter Material Design de façon très simple en éliminant le besoin de développer des Renderers custom. La feature peut s’appliquer en globalité à toute une application ou être mise en place contrôle par contrôle.

Annoncée avec la venue de la version 4.0 devant son état d’avancement cette nouvelle possibilité est intégrée dès maintenant dans la version 3.6 des Xamarin.Forms.


D’autres nouveautés

Même si l’essentiel est à venir dans la version 4.0 on notera que d’autres nouveautés accompagnent la venue de Visual, notamment le IsReadOnly sur les Entry et ItemSource et ItemTemplate pour le contrôle Map.

Vous pouvez voir à l’œuvre tout cela en jouant avec l’application The Little Things Playground (cliquez sur le lien pour accéder au Git du projet).

Comme chaque release la 3.6 vient aussi avec son lot de corrections et +40 fix ont été ajoutés, principalement par la communauté puisque rappelons-le les Xamarin.Forms sont Open Source et qu’une communauté active de développeur épaule les équipes de Microsoft dans leur développement et leur amélioration !

Conclusion

Les Xamarin.Forms avancent, pas toujours comme une fusée mais assurément comme un rouleau compresseur, alignant à chaque version de plus en plus de possibilités, de liberté et de simplicité. N’oubliez pas de mettre à jour vos projets avec la V 3.6 pour profiter de tout cela dès maintenant.

Je reviendrais plus tard sur certaines de ces nouveautés dont Visual qui apporte un confort de développement important pour maîtriser le design des Apps.

en attendant,

Stay Tuned !

Catégories: Dévelopement

Xamarin.Forms : Transformer un site Web en App !

Dot.Blog - jeu, 21/02/2019 - 17:19

Comment rendre plus attractif un site Web sur Smartphones et tablettes ? En le transformant en une App, facile d’accès par son icône, rapide, dédiée à un seul site, le vôtre, c’est un outil de promotion intéressant. Le tout en Xamarin.Forms, c’est assez facile…

Du Web à l’App il n’y a qu’un pas

Alors attention ! on se calme, il ne s’agit pas de transformer par magie un site web dynamique en une application mobile autonome. Cela n’a pas de sens d’ailleurs. En effet, si nous arrivions à transformer le code d’une application Web en une App C#/Xaml tout deviendrait figé. il faudrait alors inventer des procédés complexes pour mettre à jour l’application de façon dynamique sans la recompiler dès que le site Web changerait… Lourd, complexe, inutile.

Mieux vaut tout simplement intégrer le site web dans une App, c’est à dire jouer avec le WebView afin d’envelopper le site dans une coquille qui elle est une App, qui s’installe, se diffuse sur les Stores, qui permet d’accéder à vôtre site et pas n’importe lequel directement, etc.

Il y a d’innombrables avantages à adopter cette stratégie plutôt qu’à dire “vous n’avez qu’à aller sur mon site web avec le browser de votre smartphone”…. Franchement c’est mille fois mieux d’offrir une App, de se rappeler à l’utilisateur en distillant subtilement des “mises à jour” (bidons souvent) mais qui force l’utilisateur à se souvenir de vous…

Donc faire un “shell” Xamarin.Forms autour d’un site Web n’est pas du tout aussi stupide que ça, c’est même très intéressant voire nécessaire dans un cadre marketing.

La vidéo

C’est à la découverte de cette technique d’encapsulation de site web que ce 17eme numéro de Dot.Vlog vous entraîne !

Oui, ce sera un Vlog et non un billet aujourd’hui…

Alors suivez le guide ! Enfin le lien… : https://youtu.be/xSClwyfP53w

Le code source

Le code de Dot.Vlog est regroupé ici :

https://www.dropbox.com/sh/0n1whngngn15lps/AABGZaMDOHerCf-7EkkHW6w-a?dl=0

Conclusion

Les Xamarin.Forms permettent de faire beaucoup de choses, il suffit de se lancer et d’essayer !

Stay Tuned !

Catégories: Dévelopement

Xamarin.Forms : Gérer le groupage dans les ListView

Dot.Blog - lun, 18/02/2019 - 16:35

Présenter des informations groupées et facilement accessibles pour l’utilisateur est un passage forcé dans de nombreuses Apps. Mais la façon de grouper les données et de les afficher dans l’UI n’est pas très évident. Pourtant c’est assez simple, voyons comment procéder …

Le projet exemple

Posons tout de suite le contenu du projet exemple :

  • Une MainView
  • Un MainViewModel
  • Un Model contenant
    • Une classe Phone
    • Un Dataprovider
    • Une classe gérant un groupe de Phone

Le tout aidé d’un Mvvm Helper qui n’est pas vraiment utile dans cet exemple où l’INPC ne sera pas utilisé (vous pouvez donc zapper ou utilise le toolkit Mvvm que vous voulez).

La Mainview

Elle affiche une simple ListView en pleine page. Pas de fioriture.

Le MainViewModel

Il expose une seule propriété, la liste groupée, ce que nous allons voir plus bas.

Le Model

Il expose une classe Phone très simple, le nom du fabriquant, celui du modèle de téléphone et un prix :


Une classe gérant les groupes d’entité :

Rien de bien savant : cette classe descend d’une collection observable générique se spécialisant sur la classe Phone du modèle. On lui ajoute deux propriétés, la clé et la clé courte.

La clé sera tout simplement ici le nom du fabriquant, la liste contiendra tous les téléphones de ce dernier, et la clé courte permettra d’afficher une Jump List (ou index) sur les OS le supportant (UWP, iOS par exemple).

Enfin la classe fournisseur de données :

Cette classe statique fournit une propriété retournant tous les téléphones (Phones) ainsi qu’une méthode retournant la liste des groupes. Il s’agit d’une méthode et non d’une propriété car nous ne souhaitons pas que la génération de la liste des groupes s’effectue à chaque fois que la propriété serait invoquée (imaginons une base de données réelle en dessous les performances seraient abominables). En proposant une méthode on oblige le développeur à se créer une variable pour stocker le résultat d’un appel (donc d’une seule évaluation).

Pour Phones s’agissant d’un exemple sans base de données ni accès au réseau, la liste est une propriété car elle est initialisée une seule fois à l’instanciation de l’App. Le code ci-dessus cache les nombreuses lignes remplissant la liste de la façon suivante :

Le mécanisme de groupage

Pour qu’une ListView puisse afficher des données groupées il faut deux choses :

  • Fabriquer une structure de données gigogne adaptée
  • Appliquer des valeurs à certaines propriété de la ListView
La structure de données particulières

Sans mystère on devine cette structure dans la simple présentation du code du Modèle ci-dessus. Au départ nous disposons d’une liste de Phone, cela pourrait être n’importe quoi on l’a compris, puis nous avons une classe PhoneGroup qui descend d’une Collection observable et qui va contenir une liste de Phone semblables par leur clé. Celle-ci pouvant être n’importe quoi aussi (une propriété existante dans la classe Phone ou une construction dynamique par calcul par exemple).

Dans l’exemple j’ai choisi d’utiliser le nom du fabriquant comme clé. Toutefois PhoneGroup expose juste une propriété Key (et ShortKey) qui a l’avantage de pouvoir signifier tout ce qu’on veut. Demain si je veux offrir un groupage par tranche de prix par exemple je n’aurai pas à le faire en utilisant une propriété clé appelée “Manufacturer” ce qui serait une horreur de la programmation pas même spaghetti mais tout simplement paresseuse et mal conçue… Quant à créer une nouvelle classe PhoneGroup qui offrirait une clé spécialisée pour le prix puis une autre pour le fabriquant, que dire sinon DRY (Don’t Repeat Yourself) !

Bref pour afficher des listes groupées, il faut … une liste de … groupes !

Ces groupes seront ainsi des PhoneGroup, en tant que Collection PhoneGroup contiendra directement les données d’un groupe, en tant que nouvelle classe elle exposera la clé du groupe (Key).

Certains OS sont capables d’afficher une Jump List ou Index, par exemple une liste alphabétique sur le côté droit, ou dans UWP une page de tuiles indiquant les entêtes de groupe pour faciliter le déplacement rapide au sein de grandes listes de groupes. Pour UWP on peut facilement monter à 2 ou 3 caractères ce qui permet d’avoir des groupes assez parlants, pour iOS il ne faut qu’une lettre ou un chiffre. Android via les Xamarin.Forms ne propose rien de particulier il faudra donc construire une UI particulière si on souhaite afficher un index. Notre exemple ne le traite pas. En revanche pour les OS le supportant la classe PhoneGroup expose bien une propriété ShortKey qui pourra être exploitée pour afficher la Jump List.

la structure de donnée finale consiste donc en une collection de PhoneGroup, donc une Collection de Collections.

Pour fabriquer la structure en fonction d’un critère de groupement particulier la classe DataProvider expose la méthode GetPhonesByManufacturer qui, on le comprend facilement à son nom retournera une liste de PhoneGroup dont chacun contiendra tous les modèles de téléphone d’un fabriquant donné, le nom de ce dernier étant stocké dans Key du PhoneGroup.

Les propriétés spéciales de ListView

Nous disposons désormais de données convenablement groupées et exposant les clés des groupes. Mais encore faut-il afficher ces groupes…

C’est ici que la ListView entre en scène. Ce contrôle particulier est la star des contrôles en environnement mobile où les listes sont présentes partout. On le connaît bien, on sait qu’il peut afficher des listes de n’importe quoi pourvu qu’on lui indique une source d’item (une collection) et qu’on lui fournisse un DataTemplate pour l’affichage de chaque ligne.

Rien ne va changer ici. Mais on va utiliser de nouvelles propriétés spécifiques à 'l’affichage des groupes.

La première et la plus simple à comprendre (toujours grâce à l’usage de noms explicite et non ambigus) est IsGroupingEnabled qui doit être passée à True. C’est par ce biais que la ListView comprend que la source de données n’est plus une collection simple mais une collection de collections.

la ListView a aussi besoin d’une autre information, le binding vers la propriété qui permet d’afficher le nom du groupe. Pour cela on doit initialiser la propriété GroupDisplayBinding qui sera tout simplement ici un binding sur la propriété Key des PhoneGroup.

Pour activer l’affichage de la Jump List lorsqu’elle est supportée, nous indiquerons aussi le binding de GroupShortNameBinding, ici il pointera sur ShortKey de PhoneGroup. Cela est optionnel, le groupage fonctionne même si on n’affecte rien à cette propriété.

Et puis… rien, c’est tout !

Le reste est histoire d’affiche, donc de la fabrication du DataTemplate des lignes et éventuellement celui de GroupHeader pour moduler la façon dont le nom du groupe d’affiche dans la liste.

Jouer sur l’UI n’étant pas le sujet de ce billet je vous laisse peaufiner cela en fonction de votre App.

Le résultat

Sous Android nous aurons un affichage du type suivant (sans Jump List donc) :

Sous UWP nous verrons plutôt :

Ce qui est très ressemblant (surtout lorsqu’on réduit la fenêtre pour obtenir des proportions de types smartphone !). Mais en cliquant sur un nom de groupe et grâce à la clé courte UWP fabriquera automatiquement une Jump List pour naviguer plus vite dans la liste :

Comme vous le constatez pour UWP j’ai choisi une clé de 3 lettres, c’est assez confortable pour l’utilisateur.

La fonction qui retourne la ShortKey dans PhoneGroupe peut être adaptée avec un OnPlatform pour retourner 1 lettre pour iOS et 3 pour UWP par exemple, le code exemple ne montre pas une telle adaptation, à vous de jouer !

Le code source

Vous le retrouver sous le nom de XfGrouping.zip dans le repository de Dot.Vlog à cette adresse : http://tiny.cc/DotVlog

Conclusion

Grouper n’est pas afficher… fabriquer une structure de données pour l’affichage de listes groupées est très simple (une collection de collections). Afficher cela de façon attrayante sous tous les OS est le job du designer aidé du développeur. Template selectors, adaptations personnalisées à chaque plateformes, animations Lottie, gestion de la recherche dans la liste, etc, tout cela réclame pas mal de travail pour arriver à une App finie et déployable.

Mais rien n’est possible tant qu’on ne sait pas comment utiliser la ListView pour afficher les groupes !

J’espère vous avoir ici éclairé concernant ce point technique…

Stay Tuned !

Catégories: Dévelopement

Il y-a-t-il une vie après les démos ? Les préférences sous Xamarin.Forms

Dot.Blog - sam, 02/02/2019 - 17:05

De la coupe aux lèvres il y une certaine distance, de la démo à la réalité aussi… Partons d’un exemple concret pour en apprendre plus sur les Xamarin.Forms tout en prenant la mesure du travail à fournir pour passer d’une démo à une App réelle…

De la coupe aux lèvres

C’est en regardant une vidéo de James Montemagno, évangéliste appointé chez Microsoft pour Xamarin, qu’il m’est venu une interrogation quasi métaphysique : quel est l’intérêt d’un blog et plus d’une vidéo lorsqu’elle ne fait que dire ce qu’il y a dans la doc ?

Cette vidéo est celle de la présentation de la fonction de gestion des Préférences utilisateurs (ou plutôt leur persistance) se trouvant dans la librairie Xamarin.Essentials dont je vous ai déjà parlé ici. Durant les 5 minutes 56 secondes de cette courte présentation de l’API Preferences, dans le cadre d’une série “API of the Week” (l’API de la semaine), James montre la gestion des préférences avec une petit exemple. Rien de spécial au demeurant. 6 minutes c’est court pour traiter un sujet. C’est un format qui est à la transmission de la connaissance ce que le fastfood est à la gastronomie.

On comprend aisément qu’il existe aujourd’hui une génération YouTube qui préfère voir des vidéos plutôt que de lire. Je n’ai pas de jugement à porter, chaque génération a ses influences qu’elle n’a pas choisies car paradoxalement ce cadre a été mis en place par la génération de leur parent qui eux généralement critiquent ce changement ! Quand des gamins s’entichaient du rock’n roll dans les années 50 au grand dam des adultes, n’aurait-il pas été nécessaire de leur rappeler que ce sont ces mêmes adultes qui créaient les émissions de télé, qui détenaient les chaînes de radio etc ? Rendre coupable quelqu’un de suivre une mode qu’on a mise en place est assez gonflé… Il en fut de même pour la musique Pop, le Ska, ou YouTube aujourd’hui.

Personnellement je préfère lire, je vais plus vite à extraire l’info dont j’ai besoin. Mais quand j’avais 10 ans MSN n’existait pas, et “chatter” avec ses potes consistait dans la pratique à s’habiller et à marcher jusqu’à chez eux pour sonner à leur porte et voir s’ils étaient là ou non avant même de savoir ce qu’on allait bien pouvoir faire… Pas de nostalgie, mais il est vrai que comme la slow-food, le “slow living” imposait des temps morts propices à la rêverie qui renforce l’imaginaire et la créativité autant que des envolées de pensées plus complexes. Cela développait aussi un sens plus aigu de l’observation. Bref tout ce qui est nouveau n’est pas forcément un progrès et tout ce qui est vieux n’est pas forcément dénué d’intérêt !

La vidéo de James dont il est question s’inscrit dans cette nouveauté, cette influence du temps qui fait que les mots parlés devant une caméra semblent plus accessibles que ceux qu’on lit sur un papier ou un écran.

Quelques minutes pour présenter une API, why not ?

Ce qui m’a choqué n’est donc pas le format ni son support, dans un réflexe qui aurait alors été plus ou moins réactionnaire. Non ce qui m’a dérangé c’est que cette vidéo n’apportait vraiment rien de plus que la documentation qui tient en une page web et en 3 méthodes…

Là je me suis dit, zut, tourner une vidéo juste pour lire deux lignes sur un site web on atteint peut-être la limite du “tout vidéo”… Celle du ridicule étant dépassée.

Bien entendu il ne s’agit pas ici de critiquer le travail de James Montemagno, il s’inscrit dans l’air du temps, c’est un gars sympathique et jovial, et regarde qui veut regarder.

C’est plus une critique de cet air du temps qui fait qu’un gars comme lui ne trouve rien de choquant à lire un site web en 6 minutes sans rien y ajouter de plus.

Et puis cela soulève le problème déjà plus ancien de l’écart entre les démos et la réalité…

Dans tous mes bouquins, mes papiers, mes conférences, mes vidéos, j’essaye systématiquement de me mettre dans des conditions réelles, au moins très proches de celles-ci. Car les belles démos où tout se passe bien alors qu’on galère des heures à les reproduire c’est négatif !

C’est mauvais car on croit qu’on est un crétin, ou que le produit est nul, qu’on n’y comprend rien, que c’est bogué, on cherche à savoir légitimement pourquoi ce qui a pris 2 secondes dans la démo ne marche toujours pas au bout de 3 heures… Et c’est très démotivant je trouve. C’est de l’anti pédagogie.

Je sais que le monde va vite et qu’il faut un gag dans les 30 premières secondes à toute série sinon le spectateur zappe sur une autre chaîne… Et la pédagogie demande du temps ce qui est plutôt l’inverse de ce monde de la “jouissance instantanée”.

Mais il n’est pas interdit de réfléchir à des formats intermédiaires. Par exemple il y a Dot.Blog, c’est écrit, j’y raconte des choses comme cette longue introduction qui ne se trouve pas dans la vidéo (et oui c’est ça le truc du jour !), mais dans cette dernière, tout en conservant une limite de 20/30 minutes max, le format de “Dot.Vlog”, je tente d’être au plus près de la réalité.

Celui qui lit en apprendra un peu plus, celui qui vidéote aura tout de même l’essentiel d’une démarche réaliste.

Bref, de la démo à la réalité il y a toujours une distance et moi ce qui m’intéresse c’est de parcourir cette distance avec vous, vous aider à faire ce voyage, car, désolé James, n’importe quel couillon peut lire une doc et en faire une vidéo. Cela n’a aucun intérêt. C’est comme toujours le voyage qui compte bien plus que la destination !

La vidéo ! (la mienne)

Partant de ce constat, je me suis dit, essayons de refaire la même chose que James mais en se confrontant à tous les problèmes réels qui vont se poser. J’étais convaincu que rien ne serait aussi simple que ce qu’il montre. Forcément j’avais raison, mais là n’est pas la question je le savais dès le départ avant même d’avoir commencer à enregistrer, c’est une évidence mise en proverbe par la fameuse distance de la coupe aux lèvres. Rien de nouveau sous le soleil donc.

Et c’est ce voyage, entre une démo simpliste et le passage à la réalité que je vous invite à faire en ma compagnie dans ce nouvel épisode de Dot.Vlog :

Lien Direct : https://youtu.be/DW_xJRyFOxc

Conclusion

La pédagogie n’interdit pas le modernisme, mais ce dernier, mal “métabolisé” peut en revanche déboucher sur du vide de contenu, de sens.

Dot.Blog et Dot.Vlog tentent par leur complémentarité d’éviter cet écueil en vous proposant à la fois un support écrit et un support Vidéo le tout dans un format raisonnable qui traite bien de la réalité des problèmes abordés sans les survoler.

Le tout dans la langue de Molière, ce qui est rare en informatique.

Si cela vous plait, n’hésitez à commenter la vidéo (pas ici mais sur YouTube), mettre le fameux pouce bleu et à partager, car vous le savez l’algorithme de YouTube prend en compte ces indices de popularité pour proposer la chaîne à ceux qui ne la connaissent pas encore. Quitte à bosser gratuitement (pas de pub sur Dot.Blog et pas de monétisation sur Dot.Vlog) autant que ce soit pour le plus grand nombre !

Stay Tuned !

Catégories: Dévelopement

Xamarin.Forms : Les Bindable Layouts

Dot.Blog - ven, 18/01/2019 - 03:22

La version 3.5 des Xamarin.Forms apportent son lot de nouveautés mais surtout les BindableLayouts… Qu’est-ce donc et qu’apportent-ils ?

Version 3.5

Oui je le sais, la version  3.5 n’est qu’en preview stade 2, c’est à dire proche de la release (car d’ailleurs la version 4.0 est elle aussi en preview, ça bosse chez Microsoft !). Pour profiter de ce dont je vais vous parler il faudra donc installer la pre-2 de la version 3.5 au lieu de la version stable actuelle. Mais le temps que vous lisiez ces lignes il est fort possible, surtout dans un avenir proche, que la 3.5 soit déjà releasée… Donc pas de souci.

Bindable Layouts

D’après le nom on comprend que cela va parler de Layout<T>, comme le StackLayout par exemple, et de binding… Deux sujets importants. Le premier est une des briques de base utilisée dans presque toute mise en page Xamarin.Forms et XAML de façon plus générale (même sous d’autres noms), et le second est carrément l’âme de XAML, de WPF, UWP, de MVVM et des Xamarin.Forms ! Enlevez le binding et c’est tout cet édifice qui s’écroule.

Donc à la base c’est du lourd… Mais encore…

Les Bindable Layouts décrit un procédé qui se rapproche de celui des Behaviors, c’est un comportement attaché à un Layout<T>. Quel comportement ? Celui de supporter automatiquement une liste d’items.

Un Layout<T> qui supporte une liste d’Items, on connait déjà ça, ça s’appelle une ListView !

C’est vrai. Mais une ListView c’est beaucoup plus que ça, elle optimise la gestion des items, elle peut en gérer des centaines, elle gère le scrolling, et plein d’autres choses.

Parfois on aurait besoin d’une solution plus simple. D’autres fois on aimerait dans une ListView qu’un item puisse afficher une courte liste de sous-items. Mais n’essayez pas de mettre des ListView dans une ListView… Y’en a qui ont essayé, ils ont eu des problèmes… En réalité la façon dont la ListView gère le scrolling fait qu’il est impossible de faire la différence entre votre doigt qui se déplace pour faire défiler la liste principale ou la liste secondaire.. Donc ça ne marche pas. Pourtant une petite liste de sous-items dans un item cela n’a rien de farfelu.

Vous l’avez compris les Bindable Layouts sont tout simplement des Layout<T> qui vont – par un procédé que je vais vous expliquer – supporter par “magie” la création automatique d’items comme s’ils étaient des ListView (en moins sophistiqué).

Ces Layouts, comme le StackLayout qui s’y prête très bien, une fois branché à un BindableLayout, nouvelle classe de XF 3.5, vous ainsi devenir des conteneurs de liste capable d’afficher automatiquement des items. Le procédé n’est pas fait pour en afficher des centaines, pas de scrolling notamment, mais il est parfait pour imbriquer des listes dans des listes…

Une liste de client avec sous chaque nom de client la liste des 5 dernières commandes par exemple. Tout bête, pas farfelu du tout. Et pourquoi pas pour chaque commande la liste des 2 articles les plus chers ? etc.

Les bindable Layouts permettent ainsi non pas des fantaisies de mise en page mais une souplesse accrue qui ne pourra que nous simplifier la vie et ouvrir de nouvelles possibilités de mise en page !

Les Layouts

Un bref rappel de ce que sont les Layouts et leur généalogie :

La classe Layout<T> définit une spécialisation de Layout qui expose une collection de vues enfants. On peut ainsi ajouter ou supprimer ou même remplacer des vues enfants pour coller au design de la page.

Avec un StackLayout on peut écrire en C# le code suivant qui met en évidence cette propriété Children :

myStackLayout.Children.Add(new Label {Text=”toto”});

Layout<T> se trouve en réalité à la base de presque tous les Layouts que nous utilisons. Le StackLayout ou la Grid sont de bons exemples.

L’idée des Bindable Layouts est juste de se dire que puisque les Layout<T> ont une liste d’enfants pourquoi ne pas la rendre bindable, ce qui ouvre plein de possibilités intéressantes…

Mais comme à la base Layout<T> n’est pas prévu pour cela, c’est par le biais d’une classe particulière qu’on va ajouter cette possibilité de binding… Bien entendu l’effet va dépendre de la capacité du layout de base sur lequel on va greffer le binding. Partir d’un StackLayout ne donnera pas le même résultat qu’avec une Grid aux lignes et colonnes définies spécifiquement. Je vous laisse tester pour voir ce que cela donne !

Mais revenons à cette classe spéciale qui ajoute le binding à Layout<T> qui n’en disposait pas…

BindableLayout,  la classe !

Oui c’est la “classe” ces listes imbriquées, mais pas seulement. Et cela fonctionne grâce à une classe principale, BindableLayout qu’on peut voir comme une sorte Behavior ou plus exactement de propriété attachée qui confère un comportement particulier, celui de supporter une liste d’items.

Les principales propriétés définies par cette classe sont :

  • ItemsSource, la source des items vous l’aviez compris
  • ItemTemplate, heuu le template des items à afficher (un DataTemplate)
  • ItemTemplateSelector, le sélecteur de template s’il y en a un

Du code !

Dans la pratique comme cela marche ?

Pour ce petit exemple imaginez qu’on veuille présenter une liste d’objets sans pour autant faire appel à lune ListView. Ici l’objet de base venant du Modèle sera un Synthétiseur. On souhaite afficher la liste de quelques synthés de légende à la suite de la mise en page.

Le Model

Voici la classe unique du Model, la classe Synthesizer :

Rien de spécial donc on passe au provider de données :

Le DataProvider est ici une classe statique qui retourne une liste de synthétiseurs. Dans une App plus réel cela serait un service très certainement, les données seraient lue depuis une base de données ou bien depuis un serveur Web.

Le ViewModel

Même pour un petit exemple tout bête il ne faut pas oublier les bonnes manières ! Ze ViewModel qui va vous killer :

J’avais prévenu, c’est du ViewModel de haute voltige !

La View

On sent bien que c’est là que tout va se passer … surtout vu le niveau du code qui précède, il est temps qu’il se passe quelque chose !

Vous savez qu’en cliquant sur une image Dot.Blog vous donne la version à 100%. Je le redis pour les celles et les ceux qui non content d’avoir une vue déficiente seraient aussi affublés d’un trouble de la mémoire (étant donné que je le répète dans chaque billet ou presque). Ah ces gaulois réfractaires, fainéants et oublieux en plus ! Et ça coûte un pognon de dingue toutes ces lignes à écrire !

Donc ici nous voyons un StackLayout contenant l’essentiel de la mise en page de cette App. Il contient en effet quelques labels, des BoxView pour faire tracer des lignes, et un autre StackLayout à la fin.

C’est ici que les choses se passent. A l’intérieur de la balise du StackLayout on voir le premier appel à BindableLayout et sa propriété ItemsSource, en toute logique bindée à la collection exposée par le ViewModel.

A l’intérieur du StackLayout on ouvre d’autres balises permettant de préciser la valeur d’autres propriétés du Bindablelayout, notamment l’ItemTemplate.

S’ensuit un contenu très classique, celui de la définition d’un DataTemplate faisant usage d’une Grid à 3 colonnes pour afficher les 3 champs sur une seule ligne.

On trouve les balises fermantes de tout ce petit monde et c’est tout…

A quoi cela ressemble ?

Une image valant mille mots :

Conclusion

Les Bindable Layouts sont une nouvelle corde à notre arc. Un ajout bienvenu offrant la souplesse des listes à tous les Layouts ou presque. Listes et sous-listes deviennent ainsi bien plus faciles à créer. Même si le procédé n’est pas conçu pour gérer de grandes listes (pas de scrolling comme la ListView) il n’est pas interdit non plus de penser à des listes de quelques dizaines d’éléments, ou à des listes imbriquées et de mettre tout cela dans une ScrollView pour en autoriser le balayage … Pourquoi pas une ListView alors ? Mais elle peut très bien servir de liste principale dans ce montage, rien ne l’interdit. C’est à vous de voir en fonction du contexte et de vos besoins !

La version 4.0 déjà en preview (en même temps que la 3.5 donc) va offrir la CollectionView, plus puissante que la ListView pour gérer de nombreux items surtout lorsque la présentation de chacun peut différer. Mais nous aurons le temps d’en parler !

Pour l’instant intéressez-vous aux nouveautés de la 3.5 qui sera bientôt releasée (ou déjà selon quand vous lirez ces lignes), et notamment aux Bindable Layouts !

Stay Tuned !

Catégories: Dévelopement

Xamarin.Forms : Utiliser des contrôles natifs avec binding !

Dot.Blog - dim, 23/12/2018 - 17:08

Insérer des contrôles natifs directement en XAML ? Si c’est possible ! Avec support du Binding ? Encore oui ! Mais comment ? …

L’ouverture à son maximum, le respect des plateformes aussi !

Xamarin.Forms est livré avec plus de 40 contrôles (pages, conteneurs, contrôles…) qu’on peut combiner pour créer des interfaces utilisateur multi-plateformes natives avec un seul code centralisé. C’est déjà une prouesse ! Mais l’une des facettes qui rend Xamarin.Forms si puissant et si unique c’est que nous avons accès à 100% des contrôles et des API pour iOS, Android et Windows (et d’autres OS s’étant ajoutés avec le temps). Pour mettre en œuvre des fonctionnalités spécifiques à la plate-forme telles que la géolocalisation ou le Bluetooth, nous pouvons tirer parti du DependencyService. Pour ajouter des contrôles spécifiques à la plate-forme tels que FloatingActionButton sur Android, nous disposons de nombreuses options différentes, des rendus personnalisés aux effets en passant par l’intégration native .

L’équipe Xamarin.Forms va encore plus loin en nous proposant la déclaration de vue native qui permet d'ajouter des vues bindables iOS, Android et Windows directement au code XAML. Plutôt que d'avoir à écrire un moteur de rendu personnalisé, vous pouvez simplement ajouter le contrôle directement à XAML sans configuration supplémentaire. Déclaration de vue native

Une vue native est un contrôle propre à la plateforme cible. Par exemple sous Xamarin.Forms nous avons des abstractions comme Label pour écrire un bout de texte, ce “Label” n’existe nulle part, il est remplacé à la compilation par un contrôle natif, c’est ce qui fait de Xamarin.Forms le seul environnement cross-plateformes respectueux de ces dernières. On peut, comme évoqué plus haut, modifier la façon dont le choix du contrôle est fait, ou en modifier le comportement (avec les Effets ou les Rendus personnalisés). Mais parfois on aimerait tout simplement utiliser directement et sans détour un contrôle natif.

Prenons le Switch par exemple. Il s’avère que ce contrôle est déjà présent sous Xamarin.Forms et qu’il est déjà traduit en natif, ce qui diminue un peu l’intérêt de le substituer à la main je vous l’accorde mais c’est un contrôle simple présent sur toutes les plateformes qui permettra d’illustrer le mécanisme de déclaration native de façon très simple. Bien entendu dans ce cas précis cela n’a guère d’intérêt puisque XF le fait tout seul, mais pour que l’exemple reste court et compréhensible c’est un bon choix. A vous d’imaginer d’importe quel autre contrôle natif à la place de celui-là dans l’exemple qui suit !

Une vue native est donc un contrôle présent uniquement sur une plateforme donnée. Il possède un nom de classe et des propriétés.

La déclaration de vue native va nous permettre d’insérer directement un tel contrôle dans le XAML d’une page, d’un ContentView ou autre comme si il s’agissait d’un contrôle Xamarin.Forms ! Et même mieux, les propriétés de ce contrôle native vont pouvoir supporter le Binding aussi directement qu’un contrôle Xamarin.Forms !Exemple

J’aime commencer par la démo visuelle qui permet de mieux situer ce dont on parle. Avant de voir le code regardons ces deux run de la même application, sous Android et sous UWP (oui j’ai eu la flemme de mettre en route le Mac juste pour faire une capture écran… mais ça marche tout pareil).


Attardons-nous un instant sur cette animation. En haut de la page nous avons un titre, utilisant un Label classique de XF. En dessous nous avons une zone de saisie, elle aussi tout ce qu’il y a de plus classique, un Entry Xamarin.Forms donc.

Sous le Entry se trouve une ligne “Enable Entry ?” se terminant par un switch. C’est là que les choses sont intéressantes :

  • Ce Switch est un contrôle natif sous chaque plateforme qui sera déclaré directement en XAML (à voir plus bas)
  • Mieux, l’état de disponibilité de l’Entry est lié par Binding à l’état du Switch !

Enfin on notera une ligne de texte “TextView uniquement sous Android !” qui est une ligne utilisant directement un TextView natif Android et qui ne sera visible QUE sous Android (puisque le TextView n’existe ni sous iOS ni sous UWP). Et comme nous n’avons pas multiplié les déclarations pour les autres plateformes, ce TextView n’apparaitra que dans la mise en page sous Android.

Le texte “Dot.Blog…”’ est une watermark ajoutée au GIF lors de la capture, cela n’a aucun intérêt pour la démo…

Regardons maintenant la même application lancée sous UWP :


S’agissant de la même application Xamarin.Forms on retrouve bien entendu exactement le même comportement et la même mise en page à quelques différences près (le texte du Switch est au-dessus de ce dernier sous UWP au lieu d’être sur la même ligne sous Android, ce qui pourrait s’arranger mais ce n’est pas le propos de ce papier).Alors comment ça marche ?

Il est vrai, je le répète, que si vous utiliser un Switch Xamarin.Forms de façon classique vous ne verrez pas de différence avec cette démo car le Switch Xamarin.Forms est déjà traduit en natif. Mais il faut imaginer qu’on peut utilise n’importe quelle classe spécifique à chaque plateforme et que rien ne nous oblige à ce que le contrôle natif ait exactement le même aspect sous chaque plateforme. On peut par exemple utiliser un color picker très complet qu’une plateforme offrirait et ne mettre qu’un Entry pour saisir le code de la couleur sous une autre plateforme moins riche en contrôles…

Bon, comment ça marche donc ?

De la façon la plus simple qu’il soit… Tout tient dans la déclaration des bon namespaces XAML c’est tout…

Voici le code de la page XAML de l’exemple :<?xml version="1.0" encoding="utf-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:ios="clr-namespace:UIKit;assembly=Xamarin.iOS;targetPlatform=iOS" xmlns:androidWidget="clr-namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android" xmlns:androidLocal="clr-namespace:NativeSwitch.Droid;assembly=NativeSwitch.Droid;targetPlatform=Android" xmlns:formsandroid="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.Platform.Android;targetPlatform=Android" xmlns:win="clr-namespace:Windows.UI.Xaml.Controls;assembly=Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows" x:Class="NativeSwitch.NativeSwitchPage"> <StackLayout Margin="20"> <Label Text="Native Views Demo" FontAttributes="Bold" HorizontalOptions="Center" /> <Entry Placeholder="This Entry is bound to the native switch" IsEnabled="{Binding IsSwitchOn}" /> <ios:UISwitch On="{Binding Path=IsSwitchOn, Mode=TwoWay, UpdateSourceEventName=ValueChanged}" OnTintColor="{x:Static ios:UIColor.Red}" ThumbTintColor="{x:Static ios:UIColor.Blue}" /> <androidWidget:Switch x:Arguments="{x:Static androidLocal:MainActivity.Instance}" Checked="{Binding Path=IsSwitchOn, Mode=TwoWay, UpdateSourceEventName=CheckedChange}" Text="Enable Entry?" /> <win:ToggleSwitch Header="Enable Entry?" OffContent="No" OnContent="Yes" IsOn="{Binding IsSwitchOn, Mode=TwoWay, UpdateSourceEventName=Toggled}" /> <androidWidget:TextView Text="TextView uniquement sous Android !" x:Arguments="{x:Static formsandroid:Forms.Context}" /> </StackLayout> </ContentPage> Comme vous le voyez tout se trouve dans les namespaces XAML… et dans l’ajout ensuite de balises pour chaque contrôle comme s’il s’agissait de contrôles Xamarin.Forms…

Selon la plateforme les déclarations peuvent varier. pour UWP c’est d’une simplicité déconcertante, regarder la ligne “<win:ToggleSwtich…” pour vous en convaincre.

Pour iOS aussi les choses sont aussi simples qu’en UWP (ligne “<ios:UISwitch…”)

En revanche pour Android il y a une astuce à mettre en oeuvre, passer le contexte. On le voit dans les deux exemples Android (le TextViewx à la fin et le androidWidget:Switch). Pour passer le contexte on utilise une référence à l’instance de MainActivity (via l’extension XAML x:Static) mais pour accéder à cette instance il faut ajouter un namespace qu’on voit plus haut qui est “formsandroid”. Sinon le mécanisme est le même que pour les autre plateformes.Conclusion

Remplacer un Switch n’a pas d’intérêt, Xamarin.Forms le fait déjà pour nous depuis toujours. Mais il faut imaginer à la place de ce Switch n’importe quel contrôle natif de n’importe quelle plateforme cible… Et là ça devient tout de suite très intéressant, au moins dans certains cas.

Et de toute façon, c’est une fois de plus une ouverture supplémentaire que nous offre Xamarin.Forms et il serait bien bête de ne pas l’apprécier à sa juste valeur !

Bon dev natif loin de tous les bricolages proposés ici et ailleurs, mais avec les Xamarin.Forms !

Stay Tuned !

Catégories: Dévelopement

Xamarin.Forms : Un bouton à segments

Dot.Blog - jeu, 20/12/2018 - 16:04

Bien pratique pour permettre une sélection très visuelle le bouton à segments n’existe pas sous tous les OS, mais avec un peu d’astuce et sans code natif on peut le faire en Xamarin.Forms !

Le bouton à segments

C’est un contrôle iOS au départ. Le Segmented Control.

On peut le concevoir en première approche comme une array horizontale de boutons collés les uns aux autres.

Rien de bien extravagant mais c’est très pratique… et cela rend un choix bien plus visuel et immédiat qu’un Picker. N’oublions jamais qu’une bonne UI et une UI “lisible”, c’est à dire que moins l’utilisateur n’a besoin de réfléchir mieux c’est. Avec un Picker, il faut penser à taper dessus pour voir les options, certains utilisateurs n’y penseront même pas (débutants, personnes plus âgées et moins aguerries au numérique, etc).

L’avantage du Segmented Control est qu’il rend lisible plusieurs choses essentielles en même temps :

  • La possibilité d’un choix
  • Les valeurs possibles de ce choix

C’est tout bête mais c’est ce qui participe à un design réussi… Et c’est sur iOS que cela existe. Alors on ne s’affole pas, je n’aime pas la pomme croquée pour plein de raisons, et avant de crier au génie il faut se rappeler qu’ils en étaient encore au skeuomorphisme quand Microsoft et Android en étaient déjà à Metro ou Material Design (ou son ancêtre)…

Bref c’est pratique c’est utile et on aimerait bien en avoir l’équivalent sous toutes les plateformes, mais ce n’est pas le cas.

Il faut donc en construire un. Sans code natif c’est plus drôle, tout en Xamarin.Forms (mais graphiquement on verra qu’on peut faire mieux).

Le contrôle

Ne réinventons pas la poudre, Thiago Bertuzzi a déjà créé un tel contrôle. Comme je le disais ce n’est pas parfait, notamment si on veut ajouter un cornerRadius. Au lieu que seules les extrémités soient alors arrondies (comme on peut le voir sur l’image iOS plus haut) chaque bouton de l’ensemble le sera ce qui n’est pas le top visuellement. Je vous déconseille donc les coins arrondis avec cette version, les coins carrés c’est joli aussi, surtout si cela rend l’ensemble plus homogène.

Voici le contrôle en action, j’ai donc choisi un look rectangulaire plutôt que “mal” (ou trop) arrondi :


Je ne le dirai jamais assez mais pour vos captures écran de ce genre utilisez ScreenToGif qui est très bien fait, qui est open source, et réalisé en WPF ! (https://github.com/NickeManarin/ScreenToGif pour le code source, et ici pour la version compilée : https://www.screentogif.com/)

Comme vous le voyez sur l’animation j’ai créé trois zones avec chacune un texte. Le contrôle fonctionne avec un SelectedIndex qui retourne le bouton actif dans la range 0…nombre de boutons (-1).

Le label que j’ai placé en dessous ne fait qu’un binding au ViewModel pour récupérer le numéro du bouton sélectionné et l’afficher (via un Binding avec StringFormat bien entendu et pas un bricolage de concaténation de chaînes dans le ViewModel…).

Le XAML correspond à l’exemple est le suivant :

<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:SegButDemo" xmlns:segmentedButton="clr-namespace:Xamarin.Forms.SegmentedButton;assembly=Xamarin.Forms.SegmentedButton" x:Class="SegButDemo.MainPage"> <ContentPage.BindingContext> <local:MainViewModel/> </ContentPage.BindingContext> <StackLayout> <segmentedButton:SegmentedButtonControl DefaultColor="SlateGray" SelectedColor="Red" SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}" CornerRadius="0" HeightRequest="20" Margin="8, 8, 8, 0"> <segmentedButton:SegmentedButtonControl.LabelStyle> <Style TargetType="Label"> <Setter Property="FontSize" Value="12" /> <Setter Property="FontAttributes" Value="Bold" /> </Style> </segmentedButton:SegmentedButtonControl.LabelStyle> <segmentedButton:SegmentedButtonControl.SegmentedButtons> <segmentedButton:SegmentedButton Title="Aucun" /> <segmentedButton:SegmentedButton Title="Premier"/> <segmentedButton:SegmentedButton Title="Second"/> </segmentedButton:SegmentedButtonControl.SegmentedButtons> </segmentedButton:SegmentedButtonControl> <Label Margin="0,50,0,0" HorizontalOptions="Center" Text="{Binding SelectedIndex, StringFormat='Index sélectionné = {0}'}"/> </StackLayout>


Je vous fait grâce du ViewModel qui ne contient qu’une seule propriété, SelectedIndex de type int.

Le Package

On trouve ce package dans les nugets, sous le doux nom explicite de Xamarin.Forms.SegmentedButton.

Installez-le dans votre projet Xamarin.Forms sans le placer aussi dans les projets natifs, la construction est un contrôle composite qui ne fait pas usage d’astuces graphiques natives. C’est son avantage, et sa faiblesse aussi comme je le faisais remarquer plus haut.

Sous iOS le contrôle natif sera plus joli mais l’avantage de ce contrôle XF c’est de tourner partout avec un seul et même code central sans aucune intervention dans le code natif de chaque plateforme. Mais grâce à OnPlatform et quelques astuces par exemple on peut fort bien utiliser le contrôle natif sous iOS et le contrôle Xamarin.Forms ailleurs.

Conclusion

Avantages vs inconvénients, c’est le lot de tout développeur, savoir quand s’enquiquiner parfois beaucoup pour une petite différence, savoir quand se contenter d’un truc tout fait qui marche et pouvoir passer plus vite à la suite du projet…

Comme d’habitude c’est à vous de voir, selon les exigences de design du projet et le budget qu’on vous offre pour y arriver ! (c’est souvent là que ça coince… on veut des Ferrari au prix d’une clio…)

En tout cas, bon dev !

Et…

Stay Tuned !

Catégories: Dévelopement

Xamarin.Forms : Une ViewCell extensible

Dot.Blog - sam, 15/12/2018 - 23:07

Changer la taille d’une ViewCell à la volée dans une liste peut permettre de rendre l’affichage plus compact tout en laissant la possibilité d’en voir plus. Mais ce comportement n’existe pas de base… Il faut un peu de code !

ViewCell extensible

On peut utiliser le procédé dans de nombreuses conditions. Partout où une partie de l’information n’est pas essentielle mais est suffisamment importante pour que l’utilisateur puisse avoir besoin de la voir s’il le désire. Un exemple tout simple pourrait être d’afficher la date et l’heure de réception d’un message dans une messagerie de type WhatsApp. Les bulles des messages sont toujours affichées mais un appui long sur une bulle permettrait de voir l’horodatage ou de le faire disparaître et ce non pas globalement mais pour chaque “bulle” en particulier.

Visuellement cela donnerait quelque chose comme la petite animation ci-dessous empruntée à Alex Dunn qui a déjà écrit sur ce besoin si courant mais si peu abordé il faut l’avouer :


Bref vous comprenez le principe.

Une fois une ViewCell affichée elle ne changera pas “comme ça” de taille, il va falloir l’aider un peu. Certes il faudra un binding sur la partie à rendre visible ou non, ce qui pourra se déclencher sur un appui long par exemple, mais cela n’existe pas out –of-the-box (nous verrons plus loin comment y arriver). Sans oublier le cœur du problème qui consiste à avoir une cellule capable de forcer son changement de taille à la volée car c’est bien là qu’est l’astuce du jour !

La Cellule extensible

Commençons par là. Il nous faut une cellule “extensible”, en réalité une cellule capable de forcer le calcul de sa taille même une fois affichée.

Le code est redoutablement simple :

public class ExpandingViewCell : ViewCell { protected override void OnTapped() { base.OnTapped(); ForceUpdateSize(); } }


Ce n’est pas très compliqué, le truc consistant à détourner le OnTapped() pour effectuer un ForceUpdateSize(). Sans oublier d’appeler en premier le traitement original (base) qui permet justement d’appeler le gestionnaire qui éventuellement basculera l’état de la partie cachée à visible (et l’inverse).

Il suffit donc d’utiliser ExpandingViewCell à la place d’une ViewCell et de gérer un champ du ViewModel booléen qui passe vrai/faux l’affichage de la partie additionnelle. Cette dernière sera bindée à cette propriété bien entendu.

Il est évident que la ListView utilisée devra être placée en mode HasUnevenRows=true.

Par défaut ici c’est sur le Tap du message qu’on devra accrocher une ICommand qui effectue la bascule de la propriété.

Le mieux serait d’avoir une gestion d’appui long, mais de base cette Gesture n’existe pas sous Xamarin.Forms.

Cela peut se faire assez facilement grâce aux “Effets” Xamarin.Forms qui n’ont rien à voir avec des “effets spéciaux” mais tout à voir avec la manipulation simplifiée de code natif…

Les effets XF sont plus simples à mettre en œuvre que l’injection de code natif ou le sous-classement, méthodes plus habituelles pour modifier le comportement d’un objet. Disons que le sous-classement ou l’écriture de nouveaux contrôles se justifient pleinement lorsque ce qu’on veut faire n’existe pas du tout. Les Effets sont eux plus simples à écrire s’il s’agit juste de prendre en charge une possibilité nativement supportée mais pas incluse dans le contrôle Xamarin.Forms correspondant.

Le LongPress est de ce type, cela existe sous Android et iOS, il suffit juste d’aller le chercher pour rajouter la Gesture à tout contrôle. Comme une sorte de Behavior.

Le même Alex Dunn à qui j’ai piqué l’animation a écrit un Effet de LongPress, alors il est justice de vous renvoyer sur son site pour y repiquer le code ! Vous verrez c’est assez simple.

Conclusion

Pouvoir changer la taille d’une cellule au runtime et une fois celle-ci déjà affichée s’avère extrêmement utile en moult occasions. Et comme nous l’avons vu on peut le faire avec une ou deux lignes de code en créant une ViewCell custom.

il existe mille contextes pour exploiter cette possibilité, certains n’auront besoin de rien de plus qu’un binding qui change de vrai à faux et réciproquement pour afficher ou cacher la partie supplémentaire, dans d’autres contextes il faudra peut-être ajouter quelque artifice comme la prise en compte d’une Gesture particulière, le LongPress étant celui auquel on pense en premier en général.

Grâce aux Effets Xamarin.Forms ajouter ce comportement n’est pas un problème, surtout en utilisant le code que je vous ai donné en lien.

Une chose : n’abusez pas du procédé… Les règles du design font qu’une App doit rester lisible pour l’utilisateur, les commandes cachées, les appuis longs non documentés etc peuvent rendre l’App confuse ou tout simplement en faire perdre l’intérêt pour ceux qui n’auront pas compris l’astuce et qui ne l’utiliseront pas…

Restez toujours sobre et lisible dans vos designs… et …

Stay Tuned !

Catégories: Dévelopement

Picker pour Enum avec description et localisation sous Xamarin.Forms

Dot.Blog - mar, 11/12/2018 - 05:35

Comment permettre la sélection par l’utilisateur d’une valeur appartenant à une énumération ? En créant un Picker personnalisé ! Comment personnaliser les options ? Par des attributs ! Comment rendre tout cela traduisible ? Avec des ressources ! Tout cela vous sera divulgué dans ces deux vidéos de Dot.Vlog !

To pick or not to pick

That is the question…

En effet, les Enum (énumérations C#) sont très pratiques, elles évitent l’utilisation de chaînes de caractères, sont facilement contrôlées par le compilateur, elles se prêtent aisément à tout refactoring ou évolution, bref les Enum c’est génial.

Très souvent les Enum ont un sens pour l’utilisateur dans le cadre de son activité. Etat d’un document, d’un processus industriel, modes de règlements, etc… Il est alors très tentant de vouloir proposer une sélection directe des valeurs possibles.

Hélas aucun contrôle ne permet d’effectuer une telle sélection sur une Enum. Les listes et autres pickers acceptent des sources de données certes, mais sous forme de collections le plus souvent.

Pas de bricolage !

Le bricolage consiste comme on le voit souvent à transformer les valeurs d’une Enum en string puis à les placer dans une List<string> qu’on donnera ensuite en source de données à une ListView ou un Picker ou autre contrôle UI de sélection.

S’il faut refaire cela pour plusieurs Enum dans l’application on commence mal… sans parler qu’il va falloir ajouter du code pour traduire en sens inverse le choix de l’utilisateur, une string donc, en une valeur d’une Enum bien particulière. Ouch !

Pire encore les évolutions des Enum demanderont à modifier le code, sans rien oublier nulle part… sinon gare aux bugs !

Je pourrais continuer tellement les embuches vont s’entasser et transformer une bonne idée en une horreur.

Une solution propre

L’une des meilleurs solutions est d’isoler tous ces traitements et de les confiner dans un contrôle. C’est ça la programmation Objet dont le premier principe est l’Encapsulation !

Mais partir de rien est fastidieux, le contrôle le plus proche et le mieux approprié est le Picker. Mettons ainsi en œuvre le second principe de la programmation Objet : l’Héritage !

Nous verrons même que nous irons jusqu’à détourner le troisième principe qui est le Polymorphisme…

C’est ainsi une solution propre au sens de la programmation objet que je vais vous présenter.

Deux vidéos pour un seul sujet

Le format que j’impose à Dot.Vlog est que chaque vidéo ne doit pas dépasser 30 min et faire moins si possible. 15 à 20 min étant une bonne durée. Et certains sujets débordent de ce format. Ce fut le cas du Visual State Manager (trois vidéos !) et c’est le cas ici. Mais deux vidéos suffiront à couvrir les trois versions améliorées au fur et à mesure du Picker.

Partie 1/2

Lien direct : http://tinyurl.com/y8empbud

Partie 2/2

Lien direct : https://youtu.be/pRWX3CPXDWo

Commentaires

N’hésitez pas visionner ces vidéos directement sur Youtube et à laisser vos commentaires sur la page des vidéos. Les commentaires laissés ici ne sont pas pris en compte par l’algorithme de Youtube.

Abonnez-vous !

Allez sur YouTube et abonnez-vous à la chaîne vous serez prévenus de chaque sortie en priorité !

Profitez-en pour liker, c’est ce qui permet avec les commentaires que la chaîne soit mieux recommandée.

Vous imaginez bien que sur un tel sujet je ne risque pas d’atteindre les 10 millions de vues ni même les 10 millions d’abonnés. Soyons lucides… Cette chaîne ne sera jamais “monétisable”, et cela ne me dérange pas. Mais en revanche partagez, parlez-en à vos collègues, incitez-les à s’abonner, car passer tout ce temps à faire des vidéos n’a d’intérêt que si elles sont regardées par le plus grand nombre. Non pour mon compte en banque vous l’avez compris, ni pour la gloire (même si, sans hypocrisie, il est toujours bon d’entretenir une réputation ), mais bien pour le seul et unique plaisir de partager un savoir. C’est le seul moteur de Dot.Blog et c’est celui de Dot.Vlog.

Alors pensez à diffuser l’information autour de vous !

Bonus : le code source

Pour les courageux qui auront lu jusqu’ici voici le lien Dropbox vers le répertoire qui contient le code source de toutes les vidéos Dot.Vlog. Conservez-le, les nouveaux exemples viendront s’ajouter avec le temps….

Facile à retenir, le lien raccourci est http://tiny.cc/DotVlog

Conclusion

Les Enum ne sont vraiment pas la feature la plus exaltante de C#, mais c’est l’une des plus pratiques ! Et c’est surtout comment on s’en sert qui permet de développer des connaissances nouvelles, de la compétence et du plaisir à produire un code objet propre mais aussi des UI de meilleure qualité !

Stay Tuned !

Catégories: Dévelopement

Les messageries MVVM avec les Xamarin.Forms (partie 2/2)

Dot.Blog - mar, 04/12/2018 - 03:34

D'où viennent-elles ? A quoi servent-elles ? Quand et comment les utiliser ? Quand ne pas les utiliser ? Cette seconde partie vous montrera le code pour tout comprendre !

Partie 2/2

Cette vidéo est la suite de la partie 1 que vous trouverez ici que je vous conseille de visionner en premier, mais c’est vous qui voyez

Messageries MVVM

Tous les toolbox MVVM en propose une. Il en existe même une “out of the box” dans les Xamarin.Forms.

Mais souvent je rencontre des développeurs qui se demandent à quoi cela peut bien servir, dans quels cas ?

Il est vrai que c’est mystérieux. Le principe semble simple, mais à quel besoin correspond-t-il ? Doit-on en mettre partout, ne pas les utiliser du tout ?

Ca fait beaucoup de questions !

Pour y répondre et rester dans le format Dot.Vlog (30 min maximum) il a fallu que je coupe et découpe…

La vidéo Dot.Vlog

Et même en n’hésitant pas avec les ciseaux, ça dépassait. Alors j’ai tranché. En deux.

Voici la seconde partie, n’oubliez de voir la partie 1 (lien plus haut) !

Le lien direct (surtout pour y laisser des commentaires, ceux laissés ici ne sont pas pris en compte par l’algo de YouTube…) : https://youtu.be/f1N-hJxES3M

Bon visionnage

Et Stay Tuned !

Catégories: Dévelopement

Les messageries MVVM avec les Xamarin.Forms (partie 1/2)

Dot.Blog - lun, 03/12/2018 - 03:21

D'où viennent-elles ? A quoi servent-elles ? Quand et comment les utiliser ? Quand ne pas les utiliser ? Bref, vous saurez tout sur les messageries MVVM !

Messageries MVVM

Tous les toolbox MVVM en propose une. Il en existe même une “out of the box” dans les Xamarin.Forms.

Mais souvent je rencontre des développeurs qui se demandent à quoi cela peut bien servir, dans quels cas ?

Il est vrai que c’est mystérieux. Le principe semble simple, mais à quel besoin correspond-t-il ? Doit-on en mettre partout, ne pas les utiliser du tout ?

Ca fait beaucoup de questions !

Pour y répondre et rester dans le format Dot.Vlog (30 min maximum) il a fallu que je coupe et découpe…

La vidéo Dot.Vlog

Et même en n’hésitant pas avec les ciseaux, ça dépassait. Alors j’ai tranché. En deux.

Voici la première partie, la suite dans la prochaine vidéo !

Le lien direct (surtout pour y laisser des commentaires, ceux laissés ici ne sont pas pris en compte par l’algo de YouTube…) : https://www.youtube.com/watch?v=8r9-EC0bPVE

Bon visionnage

Et Stay Tuned !

Catégories: Dévelopement

Xamarin.Forms : le nouveau ImageButton

Dot.Blog - mar, 27/11/2018 - 16:36

Les boutons avec image font partie de ce petit groupe d’objet d’UI incontournables. Mais jusqu’ici point de bouton à image sous Xamarin.Forms, mais cela vient de changer !

ImageButton

Voici un post qui ne réclame pas de long blabla ni ne justifie une vidéo sur Dot.Vlog. Tout le monde sait ce qu’est un bouton, une image, et tout le monde a déjà vu des bouton avec texte + image.

Les présentations étant faites, depuis la version 3.4.0 des Xamarin.Forms nous avons ainsi le plaisir de trouver une nouvelle classe “ImageButton” qui remplit cet office.

Certes imparfaitement (j’ai vu quelques petits bugs de comportements un peu louche, mais comme le reste ce n’est pas à sa première release qu’il faut juger une nouveauté), mais l’ImageButton fait le job et très simplement.

Utilisations inventives

Un bouton avec image seule cela permet d’obtenir une image cliquable… Sans avoir à bricoler une image en lui ajoutant une Gesture par exemple. Ce qui n’est guère compliqué (mon livre sur les Xamarin.Forms montre des exemples de cette stratégie) mais si c’est déjà fait autant en profiter et se concentrer sur du code plus utile.

Ainsi en associant habilement les possibilités du Visual State Manager et de l’ImageButton on peut facilement créer des effets sympathiques autant que dynamiques, comme par exemple un effet visuel d’enfoncement lorsqu’on clique sur le bouton (en réalité un changement de l’échelle de l’image).

Pour ceux qui souhaiterait tout savoir sur le Visual State Manager, n’oubliez pas ma série de trois vidéos sur Dot.Vlog qui traite du sujet !

Le code suivant illustre une telle astuce :


Ce qui visuellement donnera environ cela :


Comme on le voit gérer l’effet sur le bouton ne l’empêche pas de gérer normalement son clic (mis en évidence ici par l’affichage d’un message).

Les plus perspicaces d’entre vous (et ceux qui auront suivi ma série de trois vidéos sur le VSM !) auront remarqué que l’exemple de code utilise un état “Pressed” sur le bouton. Or les CommonStates ne définissent que Normal, Focused et Disabled. Il s’agit ici d’un petit raccourci, l’état “Pressed” étant un état “custom” géré à part mais ce n’était pas l’objet du papier d’aujourd’hui…

Conclusion

Que dire de plus que merci… L’ImageButton n’est certes pas une fonction “killer”, la terre ne suspendra pas sa ronde autour de son axe ni autour du soleil. Mais c’est une modeste contribution qui simplifie la vie car des images cliquables c’est un besoin fréquent…

Stay Tuned !

Catégories: Dévelopement
S'abonner à Sleepy SME agrégateur - Dévelopement