Archives de Catégorie: .NET

Introduction aux shapefile

Une utilisation cartographique

En voulant m’intéresser à titre personnel aux données cartographiques, j’ai téléchargé sur le site de l’IGN la base de données Route 500, disponible sous licence ouverte. Cette base de données contient les données de 500 000 km de routes en France métropolitaine.

L’archive (161 Mo compressés, 857 décompressés) contient plusieurs descriptifs et des métadonnées, je ne les ai pas consultés entièrement mais je salue l’initiative de joindre des descriptifs. Qui n’a jamais téléchargé  une archive au nom obscur  et oublié distraitement son utilité plusieurs mois plus tard ? Clignement d'œil

Je ne savais pas du tout à quoi m’attendre comme format de fichier en téléchargeant cette base, uniquement l’indication “format Shapefile”.  En fouillant différents dossiers, dont je présumais que l’arborescence n’avais pas beaucoup d’importance, j’ai repéré non pas différents fichiers mais plusieurs ensembles de fichiers. En effet, chaque “fichier” semblait en fait constitué de plusieurs fichiers aux noms identiques mais  aux extensions différentes (cpg, dbf, prj, shp et shx). Aucune de ces extensions ne m’était connue, et en tant que curieux bien trop hâtif, je me suis bien entendu précipité pour essayer de lire ces fichiers au plus vite avec un éditeur de texte, bien entendu sans avoir lu la moindre documentation au préalable. Seulement, avec un éditeur de texte, seuls les fichiers prj et cpg étaient lisibles, les différents cpg contenant toujours “1252” et les différents prj contenant à chaque fois un ensemble de constantes semblables à des sortes de référentiels géographiques. Quant aux autres fichiers, les plus volumineux, ils étaient illisibles (partiellement pour les dbf et totalement pour les shx et shp). Je n’ai donc pas pu éviter de lire dans un premier temps un bref descriptif encyclopédique puis une documentation complète.

Le format

Contenu général

Habitué à parser du json, du xml, des csv ou d’autres formats simples, le format shapefile m’a beaucoup surpris au départ ! Tout d’abord, comme énoncé plus haut, il n’est non pas composé d’un fichier, ni de deux, mais de trois fichiers (minimum)! Ensuite, il est quasiment impossible (mis à part pour le fichier dbf où on devine des chaines de caractères) de lire les fichiers principaux avec un éditeur de texte. En effet, le format datant des années 90, plusieurs centaines de mégaoctets de données représentaient une empreinte de stockage important, il était alors surement impensable de stocker des données sous forme de texte brut. En prenant simplement l’exemple d’un nombre entier, celui-ci sera stocké dans exactement 4 octets en format binaire au lieu de jusqu’à 10 octets en encodage de texte brut. Ainsi, il est totalement impossible de parser le fichier sans documentation. Néanmoins celle ci n’est pas très compliquée à comprendre.

Le fichier le plus important, celui contenant les formes en elles-mêmes, le shp, est constitué de deux parties. La première partie est un en-tête de taille fixe contenant différentes métadonnées comme un type de géométrie, un nombre d’objet présent et une taille par objet. Il suffit donc ensuite de lire le fichier par blocs de taille indiquée, pour trouver le nombre préconisé d’objet au format opportun.

L’endianisme

Le premier point du format qui m’a beaucoup surpris (et mit un petit moment en difficulté) est l’endianisme. Pour ceux qui ne connaissent pas ce terme ni sa traduction anglaise (endianess), cela correspond au sens de lecture de nombres quand ceux-ci ont sur plusieurs octets. Vu qu’un exemple vaut mille discours, imaginez un nombre entier codé sur 4 octets : 0x1A2B3C4D, qui, si on le découpe en octets, se présentera pour un développeur ainsi :

Poids de l’octet 3 2 1 0
Octet 1A 2B 3C 4D

Le premier octet ainsi rencontré est l’octet de poids-fort, ce sens est appelé “Big-endian”. Celui ci à l’avantage de se lire “naturellement” pour un humain mais a l’inconvénient de devoir être lu en commençant par la fin pour une machine. Pour palier à ce problème à l’ère des premiers processeurs, certains systèmes d’exploitation ont alors implémenté le “Little-endian”, c’est à dire la lecture des octets en commençant par celui de poids faible et terminant par ceux de poids forts. Le même nombre en little-endian sera noté ainsi : 4D3C2B1A.

Poids de l’octet 0 1 2 3
Octet 4D 3C 2B 1A

Le problème qu’a le format shapefile avec l’endianisme n’est pas qu’il en utilise un différent de celui de ma machine (Windows sur x86 étant en little-endian), mais qu’il utilise les deux ! En effet, les octets de 0 à 27 du début du fichier sont composés de 7 entiers notés en big-endian puis sont suivis de deux entiers et 8 décimaux notés en…little endian ! De même pour chaque enregistrement du fichier, l’en-tête sera en big-endian alors que les enregistrements eux-mêmes sont composés d’entiers ou de décimaux en little-endian ! Il m’a donc fallu adapter les méthodes de lectures de nombres pour spécifier l’endianisme….

La projection

Il m’est venu ensuite un problème de projection vis à vis des coordonnées. Ce problème n’est pas directement lié au format shape, mais plutôt son utilisation par l’IGN et l’administration française. En effet, nous avons l’habitude d’utiliser des coordonnées dans le système WGS83 (pour World Geodetic System 1983) sous forme de degrés géographiques, ou plus communément appelées “coordonnées GPS”. Ici, les fichiers fournis présentent des données dans la projection cartographiques Lambert 93. Pour faire simple et rapide : je n’ai tout simplement pas réussi à faire la conversion, malgré de la documentation, pourtant en français, je n’arrive pas à implémenter le calcul…

Mis à part cela, une fois les en-têtes de fichiers et d’enregistrement décodés, il suffit d’implémenter la lecture des différents types de données présents, une dizaine en tout mais toujours un seul type dans un même fichier. Ce format n’est ni nouveau, ni complexe et son utilisation est répandue, maitriser son utilisation ne présente pas un gros avantage technologique. Néanmoins, implémenter tous le format peut être assez long pour une seule personne donc autant partager ce code. J’en ai donc profité pour créer un repository (en C#) sur GitHub ! N’hésitez pas à aller  voir mon code, me faire des retours, voire participer (surtout si vous-mêmes ou une de vos connaissance sait convertir des coordonnées Lambert 93 en WGS83…).

Pour la documentation des fichiers shape : ici (et un complément ici pour les fichiers dBASE). Et, encore une fois, si par chance l’un de vous saurait m’aider à implémenter ce calcul,qu’il se fasse connaitre Clignement d'œil

Par Mathieu Hollebecq

Enregistrer

L’API Streaming de Twitter avec le HttpClient .net

La recherche et le streaming

Un des fonctionnalités intéressantes de l’API Twitter est l’utilisation du Streaming. Tout comme la recherche, cette API nous permet de spécifier un mot clé et de récupérer les tweets liés à ce mot clé. Cet article a pour but de vous montrer la différence entre la recherche et le streaming sur l’API Twitter ainsi que l’implémentation de ce streaming en C#.

La différence entre l’API de recherche et l’API de streaming réside en la manière de récupérer les tweets. Avec la première, vous envoyez une requête au serveur Twitter qui vous retourne alors page par page les tweets correspondant à la recherche dans une seule et même réponse. Le fonctionnement est celui d’un échange client-serveur classique :


(crédits image : https://dev.twitter.com )

Principe du streaming

Concernant le streaming, les tweets retournés ne vont pas l’être dans une seule et même réponse. En effet le serveur maintiendra la connexion indéfiniment et dès qu’un nouveau tweet concerné par la recherche faite va être soumis à Twitter, celui ci va nous être retourné dans la foulée. Ce cas d’utilisation est notamment intéressant dans des applications de type “live tweet” :

(crédits image : https://dev.twitter.com )

Implémentation en C#

L’url de requête sera https://stream.twitter.com/1.1/statuses/filter.json en POST. A cela s’ajoute un ou plusieurs paramètres. Pour une utilisation de base, nous ajouterons le paramètre “track” qui aura comme valeur votre recherche (un hashtag ou tout simplement un mot ).

Cette requête ne semble pas compliquée, mais l’extrait de code suivant, qui fonctionne dans le cas d’une simple recherche, va ici échouer. Le souci ne vient pas directement de ce code mais de la librairie OAuth que j’avais réalisée suite à un de mes précédents articles (code source disponible en une seule classe ici : https://skydrive.live.com/?cid=230FED47B214039C&id=230FED47B214039C%212851 )

static async void ComputeStreaming(string search)
{
    OAuthRequester.ComputeHmacSha1 = ComputeHMACSHA1Hash;
    string consumerKey = "yourConsumerKey";
    string consumerSecret = "yourConsumerSecret";
    string oauthToken = "yourOAuthToken";
    string oAuthTokenSecret = "yourTokenSecret";
    string searchUrl = 
"https://stream.twitter.com/1.1/statuses/filter.json"; Dictionary<string, string> contentParams = new Dictionary<string, string>(); contentParams.Add("track", search); var searchRequest = OAuthRequester.SignRequest(HttpMethod.Post,
searchUrl, consumerKey, consumerSecret, contentParams,
oauthToken, oAuthTokenSecret);
using (StreamReader reader = new StreamReader(
await (await searchRequest).Content.ReadAsStreamAsync())) { while (!reader.EndOfStream) { string result = reader.ReadLine(); JObject root = JObject.Parse(result); Console.WriteLine(root["text"].ToString()); } } }

Il n’y pas forcément d’erreur de conception dans ma librairie, l’erreur serait similaire avec l’utilisation de “WebClient” ou “WebHttpRequest”. De la même manière, la requête sera lancée, mais rien ne sera renvoyé et au bout d’une minute, vous recevrez un timeout. Le souci provient de la manière dont HttpClient traite la réponse par défaut, le client a bien commencé à recevoir la réponse, mais il attend d’avoir reçu tous le contenu avant de renvoyer votre objet “HttpResponseMessage”. Or, le principe du streaming est de laisser la connexion ouverte et de recevoir le contenu au fur et à mesure, donc HttpClient ne peut pas gérer le cas de figure de cette manière. Mais, heureusement, il suffit d’une petite modification pour gérer le cas particulier des réponses sous forme de flux et non de sous forme de contenu entier. Il suffit de modifier l’appel de la méthode “client.SendAsync(…)”, dans notre cas, nous utiliserons la surcharge suivante:

HttpResponseMessage response = await client.SendAsync(request,
HttpCompletionOption.ResponseHeadersRead);

La différence réside en l’ajout du paramètre de type “HttpCompletionOption” qui, s’il est omis, prend par défaut la valeur “ResponseContentRead” qui signifie que HttpClient attend de recevoir tout le contenu de la réponse avant de la traiter. La valeur qui nous intéresse ici est “ResponseHeaderRead” qui signifie que la réponse sera traitée dès que les header seront reçus. Le contenu en lui même sera reçu plus tard, lors de l’appel de “ReadAsStreamAsync()”. Avec la modification de la requête, vous pouvez à présent tester le code un peu plus haut qui fonctionnera cette fois-ci (testez avec un sujet populaire du moment pour voir le streaming agir ).

Conclusion

Parfois complexe à utiliser dans certains SDK, l’API streaming de Twitter consiste en une simple requête en POST. La seule petite difficulté est de ne pas attendre de recevoir tous le contenu pour traiter la requête comme le font par défaut les clients HTTP en .net mais de la traiter dès réception des headers. HttpClient permet ce traitement particulier avec la modification du paramètre HttpCompletionOption.
La mise à jour de la classe helper OAuth 1.0 est disponible ici.

Par Mathieu Hollebecq

Migrer le LongListSelector vers Windows Phone 8

Le LongListSelector

Lors de la sortie du SDK Windows Phone 7 en 2010 certains contrôles natifs ont fait leur apparition comme l’application bar, d’autres managés hérités de Silverlight comme la ListBox. Ce dernier nous permettait d’afficher des éléments sous forme d’une liste déroulante. Mais la ListBox a été vite reconnue comme souffrant de problèmes de performances.

C’est en partie pour ces soucis de performances que le Silverlight Toolkit pour Windows Phone a intégré le contrôle LongListSelector qui nous permettait de même de faire un groupement d’éléments où la navigation d’un groupe à l’autre se faisait par l’intérmédiaire d’une “JumpList”.

Avec la sortie du SDK Windows Phone 8, celui ici intègre dorénavant directement le contrôle LongListSelector qui est à présent un contrôle natif, comme l’AppBar. Simultanément avec son arrivée  dans le SDK, il a été retiré du toolkit. Cet article a pour but de vous guider pour migrer vos projets Windows Phone 7 avec LongListSelector du toolkit vers un projet Windows Phone 8 avec LongListSelector du SDK.

Tout d’abord, les namespaces

Côté C#, aucun changement, le LongListSelector est toujours présent dans le namespace Microsoft.Phone.Controls mais si vous tentez de générer votre projet directement après le passage de votre projet en Windows Phone 8 sans mettre à jour le toolkit, le projet vous signalera un conflit de nommage. En effet, le LongListSelector sera présent deux fois dans le même namespace mais dans deux assemblies différentes. Commencez tout d’abord pour mettre à jour le tookit, vous pouvez le télécharger sur codeplex à cette adresse ou bien l’intégrer directement depuis NuGet.

Dans votre xaml, modifiez simplement le préfixe de namespace de vos LongListSelector pour passer de celui du toolkit (par défaut “toolkit:” à celui du sdk (par défaut “phone:”).

Templates et Styles

Globalement, les propriétés de styles et templates restent inchangées. La seule exception est l’ancienne propriété de template “GroupItemTemplate” qui n’existe plus et qui a été remplacée par une propriété Style “JumpListStyle” dont vous devez modifier les propriétés LayoutMode et  GridCellSize. En gros votre code passera de ceci :

<toolkit:LongListSelector.GroupItemTemplate>
   <DataTemplate>
      <Border Width="40" Height="40">
         <TextBlock Text="{Binding Key}" />
      </Border>
   </DataTemplate>
</toolkit:LongListSelector.GroupItemTemplate>

A ceci :

<phone:LongListSelector.JumpListStyle>
   <Style TargetType="phone:LongListSelector">
      <Setter Property="GridCellSize"  Value="113,113"/>
      <Setter Property="LayoutMode" Value="Grid" />
      <Setter Property="ItemTemplate">
         <Setter.Value>
            <DataTemplate>
               <Border Width="40" Height="40">
                  <TextBlock Text="{Binding Key}" />
               </Border>
            </DataTemplate>
         </Setter.Value>
      </Setter>
   </Style>
</phone:LongListSelector.JumpListStyle>

Activer le groupement

Pour utiliser le groupement dans vos LongListSelector, deux propriétés doivent être renseignées : LayoutMode et IsGroupingEnabled. La première indique si les éléments sont placés sous forme de liste dans une seule dimension ou sous forme de grille (un peu comme le controle GridView sous Windows 8). La seconde doit être obligatoirement mise à “true” pour pouvoir grouper vos éléments.

Vous devrez OBLIGATOIREMENT renseigner la propriété JumpListStyle, sous peine de faire crasher votre page (notamment lié au fait de ne pas avoir renseigné la propriété GridCellSize).

Vous pouvez, si vous le désirez, mettre la valeur “true” à la propriété “HideEmptyGroups” pour ne pas afficher les groupes qui n’ont aucun sous-élément.

Modèle supportant le groupement

Avec le LongListSelector du Toolkit, le contrôle supportait d’assembler les éléments d’un groupe dans une collection héritant directement de IEnumerable<T>, ainsi nous utilisions directement le résultat de l’appel de la methode GroupBy(…). Avec la nouvelle version du contrôle, les éléments d’un sous-groupe doivent être dans une collection héritant de IList<T>, ceci empêche d’utiliser directement le résultat de l’appel de GroupBy mais il nous suffit de passer par une petite classe générique faisant l’intermédiaire telle que celle-ci:

public class Group<Tkey, TElement> : List<TElement>
{
    public Tkey Key { get; set; }
    public Group(IGrouping<Tkey, TElement> group)
        : base(group)
    {
        this.Key = group.Key;
    }
}

Il vous suffira ensuite de suivre votre GroupBy par un Select qui vous retourne des éléments “Group” et le tour est joué pour votre liaison de données Sourire

Conclusion

Même si Visual Studio s’occupe de migrer votre projet Windows Phone 7.1 vers Windows Phone 8, certaines modification manuelles restent à faire, notamment lorsque des librairies externes au SDK sont incluses, c’est le cas pour le Windows Phone Toolkit qui n’implémente plus le LongListSelector qui est maintenant implémenté directement dans le SDK. Mais des choix de développement différents ont été fait et des petites modifications mineures restent à faire. Néanmoins nous pouvons profiter maintenant d’un LongListSelector directement présent dans le SDK et de manière native, ce qui apporte des performance améliorées.

Par Mathieu Hollebecq

Pimp ma listbox

On va découvrir ici comment éditer et transformer une ListBox. L’exemple sera fait sur du Windows Phone, mais pourra être facilement répliqué en WPF, Silverlight, … En Xaml quoi !

Je vais rapidement rappeler les bases d’une ListBox et nous passerons ensuite sur quelques exemples concrets (ListBox horizontale, ListBox wrappée).

Pour cet article, j’ai utilisé Expression Blend, qui permet d’éditer les styles rapidement et facilement :
Un clic droit sur la ListBox, et dans le menu additionnal template vous pourrez éditer facilement les éléments que je signale.

Structure d’une ListBox

Comme son nom l’indique, une ListBox sert à afficher une liste d’éléments, une collection d’objets. En plus de son template, elle est constituée de trois autres templates qui permettent de la personnaliser plus précisément. C’est à eux que l’on va s’intéresser.

Illustrons ces différents templates, avec un exemple simple : une boîte de bonbons :

  • ItemTemplate : La forme sous laquelle vont s’afficher les objets contenus dans la collection. Le bonbon brut.
  • ItemContainerStyle : Le conteneur de l’item. le papier autour du bonbon. C’est sur lui qu’on gèrera l’espacement entre chaque item.
  • ItemsPanel : Le conteneur général. La boîte.

ListBox Horizontale

En partant de cette base, comment faire une ListBox Horizontale ?

  1. On édite l’ItemsPanel, on veut un conteneur horizontal. On passe donc la propriété Orientation du StackPanel sur “Horizontal”;
  2. On revient à notre ListBox, on édite les propriétés liées au Layout, on passe HorizontalScrollBarVisibility sur “Auto” ou “Visible” et VerticalScrollBarVisibility sur “Disabled” (Si vous êtes sur Blend, et que vous ne trouvez pas ces propriétés, cliquez sur la petite flèche en bas de Layout);
  3. On édite l’ItemContainerStyle en mettant une marge à droite sur notre bordure (12px est le nombre magique en général) pour pas que les éléments soit collés;
  4. Il ne vous reste plus qu’à éditer l’ItemTemplate en quelques clics en fonction de vos goûts.

Et nous avons une belle ListBox horizontale !

ListBox Wrapped

Pour rappel, le wrap est le système qui permet à des éléments de revenir à la ligne automatiquement et de s’adapter à différentes tailles d’écrans :

image

(oui ce sont des carottes wrappées)

Donc si on a bien suivi, qu’a-t-on à faire ?

  1. Modifier l’ItemsPanel, oui ! On supprime le StackPanel qu’on remplace par le WrapPanel disponible dans le Silverlight Toolkit For Windows Phone (disponible via Nuggets);
  2. Régler l’HorizontalScrollBarVisibility et la VericalScrollBarVisibility en fonction du sens dans lequel vous voulez faire aller vos éléments (verticaux ou horizontaux);
  3. Editer l’ItemContainerStyle avec une marge en bas et à droite pour “décoller” les éléments entre eux;
  4. Et éditer l’ItemTemplate en fonction de vos goûts !

Conclusion

On a donc vu rapidement la structure d’une ListBox et comment faire facilement différents types de listes.

Par JC VASSELON

“DevFC.exe has stopped working”…

Récemment, lors d’un développement sur Windows Azure, lorsque je lançais mon rôle en mode debug, j’avais le droit systématiquement au message d’erreur suivant :

image

DevFC.exe étant le Compute Emulator des outils Windows Azure, il m’était  impossible d’exécuter mon rôle sur l’émulateur Windows Azure et donc de tester… L’erreur étant vraiment gênante et bloquante, je n’ai pas pu “abandonner” sans chercher plus loin, surtout que DevFC.exe fonctionnait correctement il y a quelque temps.

Tout d’abord, j’ai fait un petit tour dans les fichiers de log, se trouvant dans C:\Users\username\AppData\Local\dftmp\DevFCLogs. Après une petite analyse, je vois l’erreur suivante:

“ Error, 201523225, Exception occurred when trying to open service host. {0}, {1}`There is already a listener on IP endpoint 127.0.0.1:12001.  Make sure that you are not trying to use this endpoint multiple times in your application and that there are no other applications listening on this endpoint”

Clairement, cela signifie que le port 12001 que veut utiliser DevFC.exe est déjà en cours d’utilisation, je suis donc allé dans le Resource Monitor (perfmon.exe, puis “Open Resource Monitor”), dans la partie “Network”, nous pouvons voir les “listening ports”, après une recherche rapide je me suis rendu compte que le port 12001 est utilisé par “vmware-hostd.exe”. Ce processus est en fait l’outil d’accès à distance pour la gestion des machines virtuelles sous vmware 8, le port 12001 n’étant pas utilisé par la version 7 de VMware Worksation Il ne me restais plus qu’à aller dans les services (services.msc), de trouver “VMware Workstation Server” et d’arrêter ce service. Ceci étant fait, j’ai pu de nouveau debugger de manière tout à fait normale mon rôle dans l’émulateur Windows Azure Sourire

Par Mathieu Hollebecq

Programmation en Small Basic (partie 1)

Qu’est ce que Small Basic ?

Small Basic est un langage de programmation exploitant le framework .net 3.5. Il a été annoncé à la PDC (professional Developer Conference) 2008. Que nous apportait ce nouveau langage? Pour nous développeurs, rien du tout Sourire . Celui-ci se destine tout d’abord aux personnes peu ou pas initiées au développement.

La syntaxe, proche du VB.net, est assez simple, les mot-clés sont peu nombreux (donc rapidement mémorisés). L’environnement de développement est visuellement agréable à regarder avec ses couleurs et ses grosses icones. Mais surtout, il reste simple à utiliser, seules les fonctions essentielles ont été gardées. Quant au code en lui même, dès les premières lignes on peut vraiment “réaliser” quelque chose.

Ce langage est donc un langage pédagogique, très adapté pour un enfant niveau primaire ou collège voulant s’initier à la programmation. Mais il peut très bien aussi se destiner à des adultes étrangers au monde du développement et souhaitant acquérir une logique algorithmique.

Prise en main de Small Basic

Pour le télécharger et l’installer, rendez-vous simplement sur le site de small basic : http://smallbasic.com/. L’installation consiste en un assistant tout ce qu’il y a de plus classique. Le seul point sur lequel nous pouvons prêter attention est la sélection des différentes langues d’aide que vous voulez installer. Une fois la courte installation terminée, vous vous trouvez face à un environnement de développement très simplifié dont le menu n’est pas sans nous rappeler le ruban d’office.

image

Comme vous le voyez, nous n’avons pas d’explorateur de solution car notre “programme” ne peut être construit qu’à partir d’un seul fichier source, pas de fenêtre propriété, pas de fenêtre de débogage, tout a été fait pour intégrer seulement le strict minimum afin de ne pas perdre un utilisateur néophyte.

Le code de Small Basic

Quant à la syntaxe, nous nous rapprochons du VB.net avec quelques particularités :

image

Chaque instruction se termine par un retour à la ligne, comme en VB.net, sauf qu’ici la notion de “type” n’existe pas vraiment. En VB.net, nous aurions du déclarer “name” en tant que “string” et lui assigner la valeur “3” aurait été impossible. Sur le code précédent, aucune erreur n’est relevée et tout s’exécute sans problème. L’image suivante représente le résultat du code donné. Etant donné que nous assignons la valeur 3 à “name”, le programme écrira bien sur à chaque fois “Hello 3”.

image

Cet article étant une simple introduction, je ne détaillerais pas plus la syntaxe ici, néanmoins si vous arrivez à “bidouiller” et à produire un code qui vous convient, vous pouvez facilement le partager avec vos amis ou collègues grâce au bouton “Publier”. A ce moment là, votre code sera uploadé sur le site de Small basic et un lien vous sera fourni, celui-ci vous permettra d’afficher le résultat dans un navigateur grâce à Silverlight, suivi du code nécessaire pour réaliser votre “programme”. Avec Small Basic, pas de secret sur le code, chaque application publiée sera associée à son code. Si vous voulez “tester” mon code, naviguez sur http://smallbasic.com/program/?JPK986.

image

Sur la partie gauche, votre programme a été converti en Silverlight et peu ainsi être exécuté par n’importe quel utilisateur, à droite le code html pour publier votre création sur votre site web et en bas le code source.

N’oubliez pas de fouiller le site pour trouver des exemples de codes et d’applications bien réalisés, notamment un tetris et un simulateur de collisions.

Dans la prochaine partie, je vous donnerais un exemple de ce qu’on peut réaliser grâce à ce petit framework et ce langage facile à apprendre.

Par : Mathieu Hollebecq

Globalisation d’une application Windows Phone 7

La globalisation d’une application WP7 peut être un procédé laborieux. Nous allons voir dans cet article comment mettre en place l’affichage des textes en fonction de la langue de l’utilisateur.
Cet article est en grande partie un résumé illustré de la page MSDN (en anglais) suivante  : http://msdn.microsoft.com/en-us/library/ff637520%28v=VS.92%29.aspx.

Commencez par ajouter un dossier Resources à votre application qui contiendra un premier fichier Resources.resx qui sera le fichier par défaut.

Resources

Les fichiers *.resx contiennent toutes les chaînes de caractères de votre application. C’est lui qui permettra de stocker les différentes langues. Un fichier .resx correspond à une langue.
Ouvrez le fichier Resources.resx :
ResourcesOpened

La première colonne Name représente la clef de la valeur, c’est elle que vous allez binder aux propriétés qui nécessitent un texte traduit en fonction de l’utilisateurs. Elle doit être unique.
La valeur, c’est le texte qu’elle doit afficher.
Le commentaire vous permettra de savoir à quoi ça correspond.
Par exemple : Title | Titre | Titre de mon application

Pensez à mettre l’Access Modifier sur la valeur “Public” (menu déroulant entouré en bleu en haut à droite).

Ajoutez maintenant un fichier resx pour chaque langue. Votre fichier devra maintenant porter la syntaxe suivante [NomDeVotrePremierFichier].culture-language.resx
Dans notre cas, pour notre fichier Resource en français : Resources.fr-FR.resx. La liste des cultures est disponible ici : http://msdn.microsoft.com/en-us/library/ee825488%28v=cs.20%29.aspx
Bien sûr, pas la peine d’ajouter toutes les cultures. Si la langue de l’utilisateur n’est pas prévue, l’application sera dans la langue par défaut.

Faites maintenant un clic droit sur le nom de votre projet et rendez-vous dans les propriétés. Dans l’onglet Application, cliquez sur “Assembly Information…”.
En bas de la nouvelle fenêtre, dans la propriété “Neutral Language” sélectionnez la langue que traduit votre premier fichier Resources.resx. Dans notre cas “English”.
Assembly Options

Validez ces modifications et faites à nouveau un clic droit sur le nom de votre projet puis “Open folder in Windows Explorer”. Ouvrez le fichier .csproj dans un éditeur de texte puis ajoutez les différentes langues supportées entre les balises <SupportedCultures></SupportedCultures>. Dans notre cas : <SupportedCultures>en-EN;fr-FR;</SupportedCultures>

Le processus est presque terminé, il ne vous reste plus qu’à ajouter une classe Strings.cs dans le dossier des Resources qui permettra de binder les différentes valeurs à vos champs de texte :

public class Strings
{
public Strings()
{   }
private static Resources localizedresources = new Resources();
public Resources Localizedresources {
        get { return localizedresources; }
    }
}

Le nom de la classe Resources correspond bien sûr au nom de votre premier fichier Resources.

Ajoutons maintenant cette classe string dans notre feuille de style, ou dans les ressources de votre App.xaml :
<Resources:Strings x:Key= »Strings » />

Félicitation, la globalisation de votre application est terminée !
Vous pouvez binder vos chaînes de caractères globalisées de la manière suivante <TextBlock Text= »{Binding Localizedresources.Title, Source={StaticResource Strings}} »/>

Si vous souhaitez aller plus loin et globaliser vos converters, ça se passe par ici : http://blogs.dotnet-france.com/gregoryc/post/Net-e28093-Globalisation-de-la-valeur-de-ConverterParameter.aspx

Par JC VASSELON

L’impression multi-page en WPF

Vous avez déjà très certainement eu à imprimer des documents grâce à WPF. Cela se résumant souvent à un PrintDialog et à l’appel sa méthode PrintVisual. Mais cette dernière ne permet qu’une impression sur une seule et même page, si le contenu est trop grand, celui-ci risque d’être tronqué lors de l’impression.

Nous pourrions alors diviser par nous-même le contenu en plusieurs groupes de contrôles et appeler la méthode PrintVisual pour chaque “groupe”. Comme exemple, j’ai pris une ListView contenant 3000 éléments, et sur chaque page, je peux en contenir 45, imaginez que vous deviez imprimer les 67 pages par 67 appels de la méthode PrintVisual et donc autant de tâches d’impressions envoyées à l’imprimante. Ne serais-ce que pour son aspect bricolage, cette méthode est à proscrire.

Heureusement, il nous est possible d’imprimer sur plusieurs pages de manière plus élégante, nous utiliserons toujours une instance de PrintDialog, mais cette fois-ci nous appellerons la méthode PrintDocument, celle-ci a de même deux paramètres, une chaine de caractère représentant la description de l’impression et un objet de type DocumentPaginator. Si nous regardons la documentation sur le MSDN, nous voyons que cette classe est abstraite, nous allons donc créer une nouvelle classe dans notre projet que nous ferrons hériter de DocumentPaginator

public class OneFor4Paginator : DocumentPaginator
{
    public override DocumentPage GetPage(int pageNumber)
    {
        throw new NotImplementedException();
    }
    public override bool IsPageCountValid
    {
        get { throw new NotImplementedException(); }
    }
    public override int PageCount
    {
        get { throw new NotImplementedException(); }
    }
    public override Size PageSize
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
    public override IDocumentPaginatorSource Source
    {
        get { throw new NotImplementedException(); }
    }
}

Nous verrons l’implémentation détaillée des méthodes et propriétés un plus loin, mais ce qui va surtout nous intéresser ici est la propriété PageCount et la méthode GetPage(…). Comme leurs nom l’indiquent, la propriété PageCount doit retourner le nombre de pages à imprimer et la méthode GetPage retournera un objet de type DocumentPage qui représentera physiquement une page imprimée. Un petit coup d’œil sur la documentation MSDN nous montre que le constructeur de DocumentPage prend en paramètre un Visual. En regardant le diagramme de classe, on voit que UIElement hérite de Visual,  nous allons donc ici simplement utiliser un UserControl pour représenter le visuel de notre DocumentPage, celui ci contiendra uniquement une GridView avec deux colonnes dans notre cas, l’extrait de code suivant montre le conteneur parent de notre UserControl.

<Grid>
   <ListView Margin= »50″ x:Name= »liste » Grid.Row= »1″ ItemsSource= »{Binding Path=ListeItem, ElementName=Page} » ScrollViewer.VerticalScrollBarVisibility= »Hidden »>
      <ListView.View>
         <GridView>
            <GridViewColumn Header= »Id » DisplayMemberBinding= »{Binding Id} » Width= »50″ />
            <GridViewColumn Header= »Nom » DisplayMemberBinding= »{Binding Nom} » Width= »200″ />
         </GridView>
      </ListView.View>
   </ListView>
</Grid>
 

Chaque page sera totalement indépendante et recevra à sa construction les seuls éléments qu’elle doit imprimer. Le code-behind de notre UserControl sera donc le suivant :

public partial class OneFor4Page : UserControl, INotifyPropertyChanged
{
    private const double PageMargin = 15;
    private const double ElementHeight = 24;
    private IEnumerable<ModelOneFor4> _listeItem;
    public IEnumerable<ModelOneFor4> ListeItem
    {
        get { return _listeItem; }
        private set
        {
            _listeItem = value;
            this.RaisePropertyChanged(« ListeItem »);
        }
    }
    public OneFor4Page(IEnumerable<ModelOneFor4> lstItems)
    {
        ListeItems = lstItems;
        this.Margin = new Thickness(PageMargin);
        InitializeComponent();
    }
    public static int RowPerPage(double height)
    {
        return (int)Math.Floor((height – (2 * PageMargin)) / ElementHeight);
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

 

La propriété constante ElementHeight nous servira ici dans la méthode statique RowPerPage retournant le nombre d’éléments que peut contenir une page, par soucis de simplicité, nous divisons juste la hauteur disponible par la hauteur d’un élément pour obtenir ce nombre.

A présent que nous avons notre “page” retournons à notre OneFor4Paginator. Nous commençons par ajouter deux champs à notre classes, _pageSize de type System.Windows.Size et _rowsPerPage de type int. A chaque modification de la propriété PageSize, nous mettons à jour _pageSize et nous appelons la méthode de classe RowPerPage pour mettre de même à jour notre champ _rowsPerPage. Nous nous occupons ensuite de remplir les propriétés IsPageCountValid et PageCount, dans cet article, nous retournerons toujours la valeur true pour la validation du nombre de pages, quant aux nombres de pages, nous retournons simplement le nombre d’éléments à imprimer par le nombre de d’éléments par page ( vous suivez jusque là Sourire ).

Quant à la méthode GetPage, nous récupérons la ligne par laquelle nous devons commencer à imprimer grâce au numéro de page passé en paramètre ( plus par pratique que par logique, ce numéro démarre à 0 ), nous calculons le nombres d’éléments à imprimer en prenons soin de vérifier s’il reste assez d’éléments pour remplir une page et éviter une belle “ArgumentException”, puis nous appelons le constructeur de notre page. Avant de passer notre UserControl en paramètre du DocumentPage à retourner, il nous faut appeller successivement les méthodes du framework Measure et Arrange sur notre UserControl, celle-ci s’occuperons de placer tout le contenu de notre UserControl, sans elles, nous imprimerons des pages entièrement blanches…

class OneFor4Paginator : DocumentPaginator
{
    private Size _pageSize;
    IEnumerable<ModelOneFor4> _listeItems;
    private int _rowPerPage;
    public OneFor4Paginator(Size pageSize, IEnumerable<ModelOneFor4> listeItems)
    {
        this._listeItems = listeItems;
        this.PageSize = pageSize;
    }
    public override DocumentPage GetPage(int pageNumber)
    {
        int currentRow = _rowPerPage * pageNumber;
        OneFor4Page page;
        int printableRowCount = Math.Min(_rowPerPage, _listeItems.Count() – currentRow);
        page = new OneFor4Page(_listeItems.ToList().GetRange(currentRow, printableRowCount));
        page.Measure(PageSize);
        page.Arrange(new Rect(new Point(0, 0), PageSize));
        return new DocumentPage(page);
    }
    public override bool IsPageCountValid
    {
        get { return true; }
    }
    public override int PageCount
    {
        get { return (int)Math.Ceiling(_listeItems.Count() / (double)_rowPerPage); }
    }
    public override System.Windows.Size PageSize
    {
        get
        {
            return _pageSize;
        }
        set
        {
            _pageSize = value;
            _rowPerPage = OneFor4Page.RowPerPage(PageSize.Height);
        }
    }
    public override IDocumentPaginatorSource Source
    {
        get { return null; }
    }
}

Il ne nous reste plus qu’à instancier un PrintDialog et appeller la méthode PrintDocument avec en paramètre un OneFor4Paginator créée précédemment.

PrintDialog dialog = new PrintDialog();
bool? dialogResult = dialog.ShowDialog();
if (dialogResult.HasValue && dialogResult.Value)
{
    dialog.PrintDocument(new OneFor4Paginator(new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight), _listeItems), « Impression OneFor4 »);
}

 

Voilà donc une façon simple d’imprimer des documents de plusieurs pages grâce à WPF, par souci de rapidité, nous avons créé notre page en code XAML, ce qui a comme “défaut” d’imprimer quelque chose ressemblant à de simples impression écran de notre logiciel. Mais nous aurions pu tout aussi bien ré implémenter la méthode OnRender de notre UserControl et “dessiner” notre page à la main grâce au DrawingContext, avec un peu d’habitude et de la refactorisation de code, cette manière de faire peut s’avérer tout aussi rapide que la création en code xaml tout en imprimant un “vrai” document sans la sensation d’impression écran…

Aucun arbre n’a du être coupé pour tester le code de cet article, par respect de la nature, utilisez au maximum les imprimantes virtuelles pour vos tests. Microsoft XPS Document Writer ne donne certes pas toujours des aperçus réalistes mais d’autres logiciels comme PDF Créator nous permettent d’obtenir un aperçu très proche des vrais impressions.

Les recherches pour cet article ont été faites dans le cadre d’un stage pour l’entreprise SACEO et son logiciel Opisto : www.opisto.fr

Par Mathieu Hollebecq

[IC 2011] Des news de notre équipe

Quelques petites nouvelles de notre projet Food 4 All
La première rencontre avec le jury va se faire durant le Bootcamp organisé par Microsoft. Deux jours de travail intense et de confrontations avec des jurys blancs,  le 25 et 26 mars à Paris.

Au programme plusieurs présentations et démonstrations de notre projet, des ateliers de coaching… Ces deux jours nous apporterons un maximum de retours pour nous préparer à la finale. Diverses activités sportives nous permettrons de libérer les neurones en ébullitions et d’échanger avec les autres équipes !

Nous vous tiendrons au courant de notre avancée au fur et à mesure sur notre compte twitter : Onefor4 . Nous pouvons déjà vous annoncer que la partie application Windows Phone 7 avance à bon rythme et nous vous présenterons prochainement son concept ainsi que quelques screenshots.

Pour vous tenir en haleine et pour soutenir notre équipe vous pouvez  d’ores et déjà télécharger le fond d’écran Food 4 All : en haute résolution

A bientôt!

Mocker

Dans une optique de mise en place d’une plateforme d’intégration je suis amené à travailler sur les tests unitaires et plus particulièrement des Mocks. Cet article me servira de synthèse sur le principe du mocking. N’hésitez pas à apporter votre expérience sur le sujet et à compléter (ou corriger) mes dires.

Qu’est-ce que le mocking ?

Par définition, un test unitaire ne doit pas toucher au système de fichiers, à la base de données, etc. Un mock permet de simuler une classe et ses méthodes. Un mock est créé à partir de l’interface d’une classe et les valeurs de retours de chacun de ses attributs peuvent être paramétrées.
Un mock au sein d’une méthode de test permet de se concentrer uniquement sur la méthode à tester. Au premier aspect, on peut considérer que du coup le comportement de la classe sera différent lors du test (par exemple : Si on réalise le mock d’une classe uploadant un fichier, on ne réalise pas vraiment cet upload.) mais en réalité la classe dont on réalise un mock est censée avoir déjà été testée. Du coup, nos tests restent cohérents.

Différents frameworks de Mocks

RhinoMock : Apprécié, beaucoup utilisé mais peu maintenu. Apparemment pas encore de support officiel du framework 4.0

Moq : Plutôt récent, conçu pour pouvoir profiter des avantages du framework 3.5. Il tire notamment avantage des expressions lambdas. De cette manière la syntaxe reste très logique, facile à aborder et permet de profiter de l’IntelliSense.

NMock2 : Bien documenté et à jour. Très transparent mais la syntaxe est quant à elle assez verbeuse et ne permet pas l’utilisation de l’IntelliSense (un plugin pour ReSharper existe pour l’ajouter). Je trouve son utilisation moins intuitive que Moq.

Dans la suite de cet article nous allons nous intéresser aux syntaxes de Moq et de NMock2 pour générer des mocks basiques.

Comparaison Moq et NMock2

Prenons une classe basique avec une seule méthode prenant un string en paramètre et retournant un autre string :

public class MaClasse {
public string MaMethode(string maString)
{
if (maString == « ping ») return « pong »;
return « out »;
}
}

Pour utiliser Moq nous pouvons créer une interface publique de cette classe :

public Interface IMaClasse
{
string MaMethode(string maString);
}

Ou bien mettre notre classe en public et utiliser le mot clef virtual dans nos méthodes.

Nous pouvons ensuite créer notre mock :
var mock = new Mock<IMaClasse>(); //A partir de notre interface
ou
var mock = new Mock<MaClasse>(); //A partir de notre classe
Puis initialiser les valeurs que retournera notre méthode en fonction des paramètres :
mock.Setup(foo => foo.MaMethode(« ping »)).Returns(« pong »);

Ou bien, pour n’importe quelle chaîne :
mock.Setup(foo => foo.MaMethode(It.IsAny<string>())).Returns(« out »);

La classe statique It permet aussi de spécifier des Regex, intéressant dans le cas de méthodes qui doivent retourner un résultat particulier en fonction d’une valeur entrée (requête, fichier à enregistrer en fonction de leur extension, …).

Nous avons donc paramétré une valeur de retour en fonction d’un paramètre d’entré. Il nous suffit maintenant de simuler l’appel à cette méthode :
mock.Object.MaMethode(ParametreInitialiséPrécédemment);
Par exemple : String toto = mock.Object.MaMethode(« ping »);
toto égalera “pong”.

Avec NMock2, nous devons mettre nos méthodes en virtual. Le mock étant du type de l’objet à mocker nous n’utilisons pas d’interface.
On commence par créer un objet de type Mockery, qui sera en quelque sorte notre fabrique de mock :
var mockery = new Mockery();
Ensuite on crée le mock de notre classe :
var maClasseMockee = mockery.NewMock<MaClasse>();
On peut maintenant paramétrer les comportements avec la classe Expect :
Expect.Once.On(maClasseMockee).Method(« MaMethode »).With(« ping »).Will(Return.Value(« pong »));
Expect.Once.On(maClasseMockee).Method(« MaMethode »).WithAnyArguments().Will(Return.Value(« out »));
Ce lien délivre une explication très détaillée avec un schéma de l’arborescence de cette classe : http://sourceforge.net/apps/mediawiki/nmock2/index.php?title=Expectations.

En résumé, comme avec Moq, on paramètre la valeur de retour (Will(Return.Value(laValeur))) lors de l’appel d’une méthode (Method(“MaMethode”)) sur notre mock (On(maClasseMockee)) avec un paramètre spécifique (With(“ping”) ou WithAnyArguments() pour n’importe quel argument).

Et nous récupérons cette valeur en appelant notre méthode de manière transparente :
maClasseMockee.MaMethode(« ping ») retournera “pong”
maClasseMockee.MaMethode(« poc ») retournera “out”

Conclusion

A l’usage, l’utilisation de Moq a une syntaxe plus facile à aborder et plus logique.
NMock2 a par contre une utilisation plus transparente avec un mock du même type que l’objet souhaité et permet ainsi un appel classique aux méthodes. Mais sa mise en place reste lourde et moins intuitive.

Par JCVASSELON