Dot.Blog

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

De Silverlight à WinRT (partie 5)

[new:30/12/2012]Cinquième partie de cette série intitulée “De Silverlight à WinRT” visant à aider les développeurs connaissant bien Silverlight (ou WPF) à aborder WinRT et ses différences. Cette 5ème partie synthétise l’ensemble des points à connaitre.

La série “De Silverlight à WinRT” – épisodes précédents

Le lecteur intéressé trouvera sur Dot.Blog de très nombreux billets sur WinRT, Modern UI (classés parfois sous le terme Metro). Parmi ces billets voici ceux qui s’inscrivent dans la logique du présent :

 

Le dernier billet listé peut être considéré comme une introduction à la plateforme WinRT, qu’on vienne du monde Silverlight ou non.

Ce qu’il faut savoir en 10 points

Pourquoi 10 points et pas 5 ou 32… En réalité tout choix est subjectif, et celui de ces 10 points à venir l’est aussi. Mais cela permet de se faire une idée d’emblée. Dix points ça se compte sur les doigts, cela reste une quantité “raisonnable”. On évite ainsi d’effrayer le visiteur en lui parlant des 642 différences, car même si le nombre de différences réelles devait être aussi grand on aurait vite fait de les regrouper en 10 catégories pour retrouver les 10 points…

Ok. C’est artificiel. Mais cela permet de fixer le décor et de proposer un découpage des différences, nombreuses, entre Silverlight et WinRT (programmé en C#/Xaml).

Les différences fondamentales

Applications Silverlight Applications WinRT
Conçues pour le clavier et la souris Conçues pour les écrans tactiles
Environnement VS 2008 à 2012, Windows et Mac Uniquement VS 2012 et seulement sur un PC Windows 8
Accès à tous les framework .NET de 2.0 à 4.5 Uniquement le framework 4.5
Support partiel de XNA XNA est supprimé et Direct3D est accessible uniquement en C++
La majorité des applications utilise C# et XAML, quelques unes utilisent le couple VB/Xaml Choix plus vaste C#/VB/C++ avec XAML et HTML5/JS/CSS3
Les apps tournent sur PC, MAC et Linux (avec MoonLight) Les apps ne tournent que sous Windows 8
Les apps fonctionnent dans le plugin au sein d’un browser ou en mode Out Of Browser sur le bureau Les apps tournent dans un profil .NET spécial au-dessus de WinRT dans Windows 8

 

Ces différences sont vraiment essentielles et primordiales, elles tiennent à la nature intrinsèque des environnements. On notera que si Silverlight donne l’impression de toucher plus de cibles que Windows 8, cela se discute largement. D’abord parce que le support des différents browsers semble se tasser depuis Silverlight 5 et que même le support Mac parait en voie de délaissement. Ensuite parce que du côté Windows 8, certes les apps ne peuvent tourner que sous cet OS, mais c’est l’OS lui-même qui est “cross-form factor”, du smartphone au PC en passant par les tablettes.

Le cycle de vie d’une application

Du point de vue du cycle de vie Silverlight, tout comme WPF se différencient énormément de WinRT.

Une application Silverlight est exécutée et arrêtée, comme une application desktop WPF, qu’elle fonctionne in-browser ou Out-of-Browser. On retrouve là un modèle classique en place depuis des lustres.

WinRT fonctionne comme un OS de smartphone, et pour cause, il est en mesure de tourner aussi sur des unités mobiles.

Les applications sont lancées par l’utilisateur mais leur fin réelle est pilotée par l’OS avec l’existence d’une sorte de “coma”, le tomb-stoning (terme utilisé sur smartphone et pas sous Windows 8 par Microsoft bien qu’il s’agisse de la même chose).

Ci-dessous le modèle classique tel qu’utilisé par Silverlight et son plugin :

 

Ce modèle devient le suivant sous WinRT :

 

Les conventions sont plus nombreuses et plus contraignantes pour l’application, notamment à cause de l’existence de timing précis à respecter et de celle de l’état “suspendu”, le fameux “coma” évoqué plus haut.

C’est l’OS qui décide de mettre fin à une application en fonction de la mémoire libre et de ses besoins. Mais pour l’utilisateur une application Windows 8 ne s’arrête jamais : quand il la reprend, qu’elle vienne de la mémoire ou qu’elle soit rechargée puis réhydratée, elle apparait telle qu’elle était lors de sa dernière utilisation.

Cela créée des contraintes supplémentaires pour le développeur bien entendu.

Les espaces de noms

Il y a eu une réorganisation des espaces de noms, WinRT étant en lui-même très différent de .NET, la couche .NET qui est placée au-dessus a du se plier à certaines changements. Ce qui brise la compatibilité directe de certains codes XAML ou C#, même si les adaptations sont rarement difficiles à effectuer (sauf pour des fonctions ayant disparu comme les Behaviors par exemple).

Par exemple un UserControl Silverlight sera défini de la façon suivante :

<UserControl x:Class="MyTestApp.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:MyTest="clr-namespace:MyTestApp" >
</UserControl >

Sous WinRT le même contrôle sera défini comme suit :

<UserControl x:Class="MyTestApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mytest="using:MyTestApp" >
</UserControl >

 

On voit que “clr-namespace” n’est plus utilisé et que “using” le remplace, de même les assemblages ne sont plus directement nommés. Il s’agit d’une évolution accessoire mais intéressante, toutefois elle brise le code existant.

Beaucoup d’espaces de noms ont été modifiés ou renommés, beaucoup d’autres apparaissent aussi, mais c’est dans la sphère de l’UI que ces changements sont les plus importants et parfois les plus gênants.

En général un code Silverlight standard déclare les usings suivants :

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes;

 

alors que le même type de code, sous WinRT déclarera plutôt cet ensemble là :

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

 

Pour prendre connaissance plus en profondeur des changements dans les espaces de noms le lecteur peut se référer aux billets cités en début d’article (notamment celui présentant le WinRT Genome Project).

Les requêtes Web

La plupart des applications modernes font des appels au Web. Sous Silverlight certaines restrictions existaient, WinRT en impose d’autres :

  • La classe WebClient n’existe plus. On accède au Web via HttpClient sous WinRT (lorsqu’il s’agit de requêtes HTTP bien entendu)
  • La classe WebRequest dans WinRT fonctionne comme tout le reste sous cet environnement : en mode asynchrone, et sans aucune choix possible alternatif d’une version synchrone. Les parties de code utilisant de telles requêtes sont à revoir et nécessite de comprendre les nouveaux mot clés await, async et les Task<T>.
  • Tous les callbacks, comme IAsyncResult, qui peuvent être utilisés en Silverlight doivent être totalement réécrits.

 

Les différences sont marquantes à ce niveau et tout code utilisant intensivement des appels Web devra être revu sous WinRT.

Le listing suivant montre un appel utilisant WebClient sous Silverlight :

public void btnSearchClick(object sender, RoutedEventArgs e)
  {
    string topic = txtSearchTopic.Text;
    string diggUrl = String.Format(
      "http://services.digg.com/stories/topic/{0}?count=20&appkey=http%3A%2F%2Fscottgu.com", 
      topic);
 
    // Initiate Async Network
    WebClient diggService = new WebClient();
 
    diggService.DownloadStringCompleted += new   
      DownloadStringCompletedEventHandler(
      DiggService_DownloadStoriesCompleted);
    diggService.DownloadStringAsync(new Uri(diggUrl));
  } 
 
private void DiggService_DownloadStoriesCompleted(object sender, 
    DownloadStringCompletedEventArgs e)
  {  
    if (e.Error == null)
    {
      // Call a Method that parses the XML data. 
      DisplayStories(e.Result);
    }
  }

 

Voici le même code utilisant les appels Web de WinRT :

public async void btnSearchClick(object sender, RoutedEventArgs e)
  {
    // Retrieve Topic to Search for from WaterMarkTextBox
    string topic = txtSearchTopic.Text;
    // Construct Digg REST URL
    string diggUrl = String.Format(
      "http://services.digg.com/search/stories?query={0}&appkey=http://www.scottgu.com", 
      topic);
 
    // Initiate Async Network call
    var client = new HttpClient();
    var response = new HttpResponseMessage();
 
    //Get response
    response = await client.GetAsync(new Uri(diggUrl));
    Task <string > responseString = response.Content.ReadAsStringAsync();
    string result = await responseString;
 
    // Call a Method that parses the XML data 
    DisplayStories(result);
  }

 

Grâce à await et async le code est finalement plus fluide est plus clair, presque plus séquentiel bien que totalement asynchrone.

Si les bénéfices sont évidents en termes de clarté et de maintenabilité du code, là encore il y a totale incompatibilité avec l’existant qu’il faudra réécrire.

Fichiers et Isolated Storage

les applications Silverlight et WinRT tournant dans une sandbox on retrouve à peu près les mêmes contraintes par exemple lors de l’accès au système de fichiers ou à l’Isolated Storage.

Toutefois, ici aussi, les nuances de concept et surtout de programmation sont nombreuses.

Malgré tout, en ce qui concerne l’Isolated Storage concept et techniques d’accès sont parfaitement équivalents. On peut créer, lire, mettre à jour ou supprimer n’importe quel fichier à l’intérieur de l’IS privé de l’application.

Pour les folders spéciaux, dont “Mes Documents” ou “Mes Images” il existe la possibilité sous WinRT d’utiliser un File Picker. Si on veut éviter cette intervention de l’utilisateur il faut réclamer les droits via le Manifeste de l’application. Une facilité non offerte aux applications Silverlight (en mode Web sans élévation de droit).

Pour tous les autres emplacements sur les disques locaux, WinRT offre le même mécanisme, c’est à dire un accès en lecture et écriture via le File Picker. Mais il reste impossible d’écrire dans un répertoire (comme le C:\temp par exemple) sans avoir réclamé l’autorisation à l’utilisateur. Sous Silverlight 5 il est possible d’éviter cela en utilisant les élévations de droit.

Comme on le voit, si les fondamentaux d’un runtime sanboxé se retrouvent dans les deux environnements, il y a autant de différences que de similitudes ce qui rend le “jonglage” un peu délicat lorsqu’on porte un code de Silverlight vers WinRT.

Navigation

Silverlight propose une service de navigation basé sur des URI. On l’utilise assez facilement avec du code de ce type pour changer de page :

this.NavigationService.Navigate(new Uri("/MaPage2.xaml", UriKind.Relative));

 

Personnellement c’est un procédé que j’utilise rarement, utilisant Silverlight pour créer des applications LOB et non des applications mimant le Web. De fait mes applications utilisent plutôt un Shell avec une plusieurs régions et les pages sont généralement des UserControl disposant d’un ViewModel. De plus, ce qui est propre au Web dans sa navigation (pouvoir aller en arrière et en avant) s’accorde assez mal avec des applications LOB.

Il n’en reste pas moins vrai que le système de navigation de Silverlight, et notamment le deep linking, peuvent rendre de grands services ponctuellement.

Sous WinRT on retrouve aussi un service de navigation fonctionnant sur des principes assez similaire (type Web donc) mais avec une implémentation radicalement différente. Là encore la compatibilité est brisée.

Sous WinRT ce service utilise un composant Frame qui, en généralement, utilise un UriMapper qui joue l’aiguilleur. C’est un peu plus sophistiqué que sous Silverlight, peut-être un peu plus souple, mais cela réclame aussi plus de travail que la simple ligne donnée en exemple plus haut. Voici à titre d’illustration une Frame WinRT utilisant un UriMapper pour gérer la navigation dans l’application :

<navigation:Frame x:Name="ContentFrame" 
  Style="{StaticResource ContentFrameStyle}" 
  Source="/Home" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed" >
  <navigation:Frame.UriMapper >
    <uriMapper:UriMapper >
      <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/ >
      <uriMapper:UriMapping Uri="/{pageName}" 
         MappedUri="/Views/{pageName}.xaml"/ >
    </uriMapper:UriMapper >
  </navigation:Frame.UriMapper >
</navigation:Frame >

La navigation dans le code s’écrira alors :

this.Frame.Navigate(typeof(NewPage));

 

Il n’y a plus d’URI mais un type. WinRT gère aussi le passage de paramètres qui pourront être récupérés par la page appelée dans les arguments de l’évènement OnNavigatedTo :

this.Frame.Navigate(typeof(NewPage),new CustomerInfo{Id=5236});

 

En dehors des nuances d’implémentation on retrouve malgré tout le même esprit avec les classes Frame et Page. On retrouve aussi tout ce qu’il y a de frustrant, à mon avis, dans ces procédés de navigation de type Web peu assortis aux exigences d’applications LOB.

Les Contrôles

De très nombreux contrôles de Silverlight sont absent de WinRT. On peut supposer que comme certaines features de XAML (tels les Behaviors) il s’agit vraisemblablement d’un manque de temps pour tout faire dans la première release de Windows 8. Mais quel que soient les raisons de ces absences, il faut convenir qu’elles sont à la base d’une cassure de compatibilité importante puisque les UI sont impactées.

Par exemple, il n’y a plus (ou pas encore) de Calendar, de ChildWindow, de DataGrid, de Treeview, etc. Autant de contrôles utilisés assez largement sous Silverlight.

Toutefois il ne faut pas non plus trop penser “transposition”. Je ne crois pas au portage massif d’applications Silverlight vers WinRT. En revanche je crois en la portabilité, avérée, du savoir-faire Silverlight qui permet d’aborder facilement le développement WinRT.

De fait, certains contrôles Silverlight absents de WinRT sont remplacés par des versions plus adaptées au tactile où à l’UX et à l’UI Metro.

Par exemple le ListView affiche une liste d’Items qui, de prime abord, le fait ressembler beaucoup à une ListBox. Le GridView offre un layout de type Grid mais avec le groupage des items. Le Zoom sémantique rend certains affichage Silverlight caduques car ici c’est l’UX que l’on modifie totalement. Le Media player est très proche du MediaElement mais possède ses propres boutons (au lieu d’avoir à les ajouter sous Silverlight). La Progress Ring remplace le progress Indicator de Silverlight avec une animation en cercle typique de Windows 8. L’application Bar remplace les menus, le CarouselPanel ou la WrapGrid sont de nouveaux contrôles intéressants. L’intégration dans les Charmes de recherche ou de gestion des paramètres modifie totalement la logique de ces fonctions et donc leur implémentation autant que leur aspect visuel, etc…

En réalité, une interface Modern UI est très différente de celle d’une application Silverlight, pas tellement du point de vue technique mais de celui de l’UX. Et ces changements de l’UX, la nécessite aussi de s’intégrer dans un tout, là où un site Web peut être totalement différent des autres, obligent à repenser l’approche de l’UI. La simple prise en compte du tactile (et de la taille minimale des éléments pour qu’un doigt puisse “'cliquer” sans “baver” sur les contrôles adjacents) implique de repenser les mises en page.

Une application bien faite, respectant MVVM, ne sera pas trop difficile à porter, mais bien que Silverlight et WinRT utilisent Xaml il faut les considérer comme des plateformes différentes.

Néanmoins, comme je le disais un peu plus haut, il faut se réjouir des res

semblances entre Silverlight et WinRT (en C#/Xaml) du point de vue de la “portabilité de notre savoir-faire” bien plus que de celle des applications.

Les animations

Animer une UI semblait un peu gadget à la sortie de Silverlight, tout le monde il est vrai pensait à l’utilisation souvent cheap qu’il était fait de cette fonctionnalité avec les bandeaux de pub en Flash…

Faire entrer les animations comme des éléments à part entière de l’UX et de l’UI et au sein d’applications “sérieuses” a été certainement la mission la moins discourue mais la plus moderne de Silverlight et WPF.

Dans un billet “fondateur” de ma vision de l’avenir (La cassure conceptuelle) j’invitais déjà en 2009 le lecteur à s’interroger sur la conception de nouvelles UI et d’une nouvelle UX totalement détachées du clavier, de la souris et des représentations habituelles des données. Les animations comptent pour beaucoup dans cette “nouvelle vision” (entre guillemets vu de quand date ce billet, même s’il reste très avance encore aujourd’hui).

Windows 8 fait un pas de plus vers les concepts que j’évoquais alors. Et notamment du côté des animations puisque tout sous Windows 8 est animé. Ces animations sont souvent discrètes (et heureusement !), elle servent à la fois la compréhension de l’action et l’esthétique, c’est à dire le besoin d’un peu de beauté dans notre métier habitué aux grilles de chiffres et aux UI tristes à mourir de type XP.

Il y a donc beaucoup de choses sous WinRT côté animation, notamment beaucoup de comportements animés fournis de base en respect avec le look and feel global de Windows 8. Sous Silverlight il faut tout inventer à chaque fois pour chaque application.

En dehors de cette avancée conceptuelle, les animations de WinRT (en Xaml) fonctionnent comme celles de Silverlight.

Les Charmes

Je les ai évoqués déjà dans ce billet. Ils jouent un rôle essentiels dans la nouvelle interface de Windows 8. Recherches, paramètres, partage de données, ils sont la clé d’une nouvelle façon d’architecturer une application comme appartenant à un tout.

Bien entendu cela implique moins de “folie” et plus de “standardisation”. Mais Microsoft veut que l’utilisateur connaisse une UX homogène à l’intérieur de Windows 8. Et c’est une bonne chose.

Les Charmes rendent des services qui n’existent pas en Silverlight puisqu’une application Silverlight n’est qu’une page Web un peu spéciale dans un browser au look particulier changeant par nature entre éditeur. Sous Windows 8 l’harmonisation est un élément essentiel de l’UX.

La monétisation

Le meilleur et le pire dans Windows 8 c’est le market place.

Le meilleur parce que cela permet aux développeurs de diffuser largement leurs logiciels et d’espérer en tirer un profit financier, le tout régit par Microsoft avec toute la confiance qu’on peut avoir en cette société.

Le market place créé un lien de confiance entre le client et le développeur, l’assurance d’une certaine qualité (purement technique) pour le premier, notamment l’absence de virus, et l’assurance d’être payé pour le second.

Je disais le “pire” aussi… Car hélas nous ne sommes pas dans le monde des Bisounours.

Microsoft emboite le pas à Apple et Google pour créer un marché totalement verrouillé dans lequel le développeur et le client sont captifs, enfermés dans un système monopolistique qui n’est pas sans poser de problème sous Windows où un long historique existe avec de nombreux éditeurs, dont certains puissants, ne veulent pas devenir captifs du market place.

Faudra-t-il maintenir at vitam aeternam un “bureau classique” pour les logiciels haut de gamme comme Illustrator et un market place pour le “second choix” ? Cela a-t-il même un sens ? Qui vivra verra !

Conclusion

Windows 8, avec C# et XAML, est un environnement plaisant dans lequel un développeur Silverlight ou WPF n’a finalement que peu à apprendre pour devenir productif.

C’est un avantage certain, d’autant que cet effort d’apprentissage très réduit ouvre la porte aux tablettes et aux smartphones.

 

Stay Tuned !

blog comments powered by Disqus