Browsed by
Month: April 2012

Comment sauter une ligne dans un textblock

Comment sauter une ligne dans un textblock

Gérer manuellement les sauts de ligne dans un textblock est une problématique qui peut revenir souvent lorsque que l’on commence à développer des UI XAML.

Si le texte est bindé, à ce moment là aucun soucis, mais si le texte est en dur dans le xaml, il est de base impossible de le faire.

Par exemple si on écrit :

<TextBlock>
<TextBlock.Text>
Bonjour
toi
</TextBlock.Text>
</TextBlock>

 

De même

<TextBlock Text="BonjournToi" />

n’est pas plus concluant.

Une possibilité

BonjourToi

Autant le dire tout de suite, je suis vraiment pas fan de cette solution, car un peu bordélique, prends de la place pour pas grand chose et surtout pas Blend-compliant, en effet, dans les propriétés de Blend, seul “Bonjour” pourra être visible parfois. Enfin gros point négatif, un espace sera rajouté après chaque saut de ligne si vous formattez votre XAML :

Bonjour
Toi

Vous aurez :

Sauf si vous demandez explicitement d’ignorer les espaces, mais vous pourrez rencontrer d’autres soucis.

Enfin un saut de ligne n’est pas un élément visuel d’interface, l’élément XAML LineBreak dénote donc avec le reste de la structure XAML.

(Et accessoirement, pas cool pour mes outils perso d’analyse de code, mais ça c’est mon problème :D)

L’astuce !

&#10;

C’est un peu barbare mais ça fonctionne :

<TextBlock Text="Bonjour Toi" />

affiche bien

Pourquoi ?

Décomposons le code &#10;

& et ; délimite en xml les caractères spéciaux, comme par exemple &amp; pour le caractère “Et commercial” ou &nbsp; pour l’espace.

“#” indique que l’on va indiquer un nombre correspondant au code du caractère.

“10” est le nombre en question.

Donc pour résumer, via ce code, on ajoute le caractère ayant le code 10 soit… le saut de ligne.

Si vous êtes un vrai geek comme moi, vous pouvez vous compliquer un peu la vie en utilisant le code suivant :

&#x0a;

Qui est exactement le même caractère, que l’on adresse cette fois en hexadécimal.

Attention à Blend

Une petite note, si vous écrivez le code &#10; dans les propriétés de blend par exemple, ce dernier va remplacer automatiquement le caractère & par &amp; (vu que c’est un caractère spécial), le saut de ligne ne se fera pas et &#10; sera visible dans votre textbox, la seule solution est donc d’éditer directement le XAML.

Comment gérer plusieurs versions de son application sans se prendre la tête : Part 2

Comment gérer plusieurs versions de son application sans se prendre la tête : Part 2

Nous avons vu dans la partie 1 comment gérer la configuration de ses projets et de sa solution, puis nous avons vu comment différencier le fonctionnel de notre application, reste maintenant la partie sensible : comment gérer les icônes et les tuiles de notre application.

Les faits

Contrairement au code, il est impossible d’utiliser les variables de précompilation pour modifier l’image ou pour en sélectionner une, nous allons donc voir comment outre passer cette limite via un petit hack assez sympa.

L’idéal serait d’avoir deux jeux d’icônes dans notre projet et de sélectionner la bonne selon la configuration, nous allons donc voir comment faire cela.

Préparation

Ajoutons deux images à notre projet, ApplicationIconFree.png et ApplicationIconPremium.png, correspondant respectivement aux icônes pour la version free et la version premium.

Faites clic droit, propriété et modifiez leurs “build action”  en…. none. En effet, elle n’ont rien à faire dans notre xap final, l’intérêt de les ajouter aux projets est toutefois multiple, dont le principal est de ne pas s’embêter avec TFS par exemple pour le versioning.

Faites de même avec BackgroundFree.png et BackgroundPremium.png pour le fond de la tuile.

 

Let’s go

Nous avons maintenant l’ensemble des ressources que l’on a besoin.

Allez dans les propriétés du projet correspondant à votre application et allez dans l’onglet “Build Events”, dans le champ “Pre-build event command line”, entrez :

if "$(ConfigurationName)" == "Release Free" (
copy "$(ProjectDir)BackgroundFree.png" "$(ProjectDir)Background.png"
copy "$(ProjectDir)ApplicationIconFree.png" "$(ProjectDir)ApplicationIcon.png"
) else (
copy "$(ProjectDir)BackgroundPremium.png" "$(ProjectDir)Background.png"
copy "$(ProjectDir)ApplicationIconPremium.png" "$(ProjectDir)ApplicationIcon.png"
)

 

Le script ci-dessus va s’exécuter juste avant la compilation. Nous regardons si nous somme en version Free en utilisant la variable “ConfigurationName”, et nous copions la bonne ressource vers Background.png et ApplicationIcon.png.

Et c’est tout, vous aurez maintenant deux icônes différentes et deux tuiles différentes selon la version de votre application.

TFS n’est pas mon ami

Si, si, TFS est cool, mais comme tous les amis, il est un peu lourd des fois. En effet, si vous avez versionné vos images Background.png et ApplicationIcon.png, alors elles sont verrouillées pour ne pas être modifié, vous avez besoin des droits administrateur, ce que n’a pas le script de prebuild. Ce n’est pas vraiment un problème, nous allons simplement les… supprimer du projets…

Bon, j’avoue, cela peut paraître étrange, mais lors de la création du xap, visual ne cherche pas les images dans notre projet, mais dans le répertoire du projet, il n’a donc aucune nécessité d’avoir Background.png et ApplicationIcon.png dans le projet. En les supprimant, TFS ne les versionnera plus, ne mettra donc pas de verrou dessus, et le remplacement des fichiers se fera sans problème durant la précompilation.

J’espère que ce guide vous aura aidé, bon dev !

 Et si j’ai + de 10 versions d’applications ?

Bon dans ce cas la, il va falloir penser à automatiser la génération d’applications. Pour cela, je rappelerais juste qu’un XAP n’est qu’un ZIP dans les faits, donc créez un petit script qui ouvre le xap (le zip), modifie les fichiers images, un fichier de configuration xml contenant toutes les informations variables (nom du club de foot, l’uri du flux RSS, etc…) et qui rezippe le tout avec un nouveau nom (bon, vous pouvez même vous épargnez l’étape dezippage/rezippage si vous avez un outils d’ajout de fichier dans un zip).

Et voilà, c’est pas plus dur que cela

Comment gérer plusieurs versions de son application sans se prendre la tête : Part 1

Comment gérer plusieurs versions de son application sans se prendre la tête : Part 1

Pour différente raison, on peut parfois avoir besoin d’avoir plusieurs versions d’une même application, comme par exemple :

  • une version complète et une version Lite, comme TVShow
  • une version normal et une version donation comme Space Shooterz
  • une application d’actu sportive par club, comme la série d’app ClevFoot
  • etc…

Je vais donc vous expliquer comment gérer ce genre d’application sans vous prendre la tête avec 12 copies de votre projet ou en modifiant à la volée vos ressources pour chaque application. Contrainte supplémentaire, nous allons essayer d’utiliser uniquement visual studio pour cela sans add-in.

Configuration de la solution

Nous allons commencer par créer autant de configuration de compilation que l’on a de version.

Par défaut, dans visual studio, vous en avez deux : Debug et Release, nous allons donc modifier Release en “Release Free” et ajouter une configuration “Release Premium” de sorte à avoir :

  • Debug
  • Release Free : compilation de la version Free (avec une pub par exemple et des fonctionnalités en moins)
  • Release Premium : compilation de la version payante

Voila comment faire :

Renommer la version Release en “Release Free”

Dans le menu “Build”, sélectionnez le menu “Configuration manager”.

Dans la liste déroulante, sélectionnez “Edit…”, puis “Release” et cliquez sur “Rename” et changez le en “Release Free”

Nous avons donc maintenant deux configuration : “Debug” et “Release Free”, ajoutons la 3ème configuration “Release Premium”.

Toujours dans la fenêtre configuration manager, sélectionnez dans la liste déroulante “New…”, entrez comme nom “Release Premium” et indiquez que vous voulez copier la configuration de “Release Free”.

 

Configuration des projets

Nous avons donc maintenant toutes nos configurations de notre solution, reste à gérer les projets :

Toujours dans Configuration Manager, sélectionnez Release Free et dans la liste des projets, renommez les configurations en “release free”, il n’est pas forcément nécessaire de le faire pour l’ensemble des projets, faites le uniquement pour les projets qui nécessite des modifications entre vos différentes versions.

De même, sélectionnez Release Premium maintenant dans “Active solution configuration” et créez une nouvelle configuration nommée “Release Premium” pour vos projets en copiant la configuration “Release Free” :

Dernier point pour la configuration, nous allons rajouter un flag de précompilation pour indiquer au compilateur si l’on est en version free ou premium, pour cela, dans les projets concerné (en ayant fait attention que l’on est bien dans le mode “release free”, allez dans les propriétés du projet et sélectionnez l’onglet “Build” et ajoutez le flag “FREE_VERSION” dans le champ “conditional compilation symbols” :

Et c’est tout !!! Enfin pour la configuration.

Différencier le fonctionnelle des deux versions

En utilisant notre nouveau flag de précompilation, nous allons pouvoir différencier le code pour la version gratuite du code pour la version payante. En écrivant par exemple :

#if FREE_VERSION
MessageBox.Show("Free version");
#else
MessageBox.Show("Full version");
#endif

Dans un cas plus concret, on pourra par exemple écrire :

private void DoAction_Click(object sender, RoutedEventArgs e)
{
#if FREE_VERSION
MessageBox.Show("Fonction non accessible en version gratuite.");
#else
DoSomething();
#endif

}

ou encore :

public MainPage()
{
InitializeComponent();
#if FREE_VERSION
ButtonBuyThisApp.Visibility=Visibility.Visible;
#endif
}

Compilez maintenant votre application en release free, puis en release premium, vous verrez alors deux répertoire dans “Bin”, contenant chacun une version différente de l’application.

Dans notre cas, la version Debug sera l’équivalent de la version Premium (fonctionnellement)

Dans la partie 2, nous allons voir comment modifier l’icone de l’application ainsi que sa tuile selon la configuration

La suite

Facebook doesn't like windows phone

Facebook doesn't like windows phone

While I did the last change of my new application (9gag), I discover a big problem with facebook API and Windows Phone.

If you create a new Facebook application and use it in your windows phone application (using the facebook sdk library for example), you will be surprised to see the following message when try to sign in :
An error has occured with 9gag. Try later.
API Error Code: 11
API Error Description: This method is deprecated
Error Message: Display=wap dialogs have been deprecated. You can temporarily enable them by disabling the “july_2012” migration. Thery will stop working permanently on July 1, 2012

Two comments :

  • I don’t use the display mode “wap”, I use “touch” in my code
  • Why do i need to disable a future update now ?
In fact the update is still here, “july 2012” it’s in fact the date where old application will be forced to use the new api. If you create a new facebook application, you use already the new api.

If we analyze the changelog, we can see that the “wap” display mode will be stopped, it should not be any problem with my application cause I explicitly asked the display mode “touch”, but that’s when I realized that facebook is not cool with windows phone :

Facebook refuses to display facebook pages with display “touch” with IE9 (mobile or desktop) and it replaces them with the display “wap”.

So, to cut a long story short: new applications must use the new api without the display mode “wap” and if you try to display the touch mode with windows phone, Facebook will use the  forgiven display mode “wap” (and display an error)

Solution

It is not possible to a new application to use the old API so, the only solution is to use a display mode different than wap and touch, so we haven’t a large choice : popup and page… two modes for desktop not for mobiles…, but we don’t have the choice.

So if you use facebook SDK, do not forget to use:

parameters[“display”] = “popup”;

instead of

parameters[“display”] = “touch”;

And if it works for me now?

If your application has at least a few weeks, yes, you don’t have this problem, because facebook migrates you in July 2012.

An option is normally visible in your interface “developers.facebook.com” in the “Advanced” tab :

This means that on July 1, you also get surprised with the above error message  if facebook do nothing…

l'api Facebook n'aime pas windows phone…

l'api Facebook n'aime pas windows phone…

Alors que j’étais en train de peaufiner ma nouvelle application (autour du site 9gag) en migrant l’id de l’application facebook vers une nouvelle application facebook tout fraichement créé (mes amis facebook ont pu voir que je faisais mes tests avec l’app id de tvshow… dsl :D), j’ai eu la grosse surprise de voir le message suivant d’affiché alors que j’avais juste changé l’id facebook de l’application :
Une erreur s’est produite avec 9gag. Veuillez réessayer tard.
API Error Code: 11
API Error Description: This method is deprecated
Error Message: Display=wap dialogs have been deprecated. You can temporarily enable them by disabling the “july_2012” migration. Thery will stop working permanently on July 1, 2012
Trois choses :
  • facebook devrait revoir ses traductions en français (ou alors il faut vraiment que je réessaie à 3h du matin ???)
  • Je n’utilise pas le mode display=wap, mais display=touch
  • Pourquoi je devrais désactiver une mise à jour “juillet 2012” alors qu’on est en avril, elle ne devrait donc pas avoir eu lieu…
Bon, en fait la mise à jour est déjà faite, “juillet 2012” c’est la date ou elle sera forcé pour les applications facebook ayant été créé il y a quelques mois déjà, la mise à jour étant déjà effective pour les nouvelles applications facebook, comme c’est mon cas.
Si on regarde le changelog de la mise à jour, on peut noter la suppression du mode display=wap, cela ne devrait pas poser problème vis à vis de mon application vu que je demande explicitement le mode display=touch, mais c’est là que je me suis rendu compte que facebook n’est pas cool avec windows phone :
Facebook refuse d’afficher les pages facebook avec le display “touch” sous IE9 (mobile ou desktop) et les remplacent par le display “wap”.
On arrive donc à un super scénario où : les nouvelles applications sont obligées d’utiliser la nouvelle api sans “wap” et quand elle tente d’afficher le display “touch”, elles sont redirigé vers “wap”, qui leur est refusé…

Solution

Il n’est pas possible de demander à utiliser l’ancienne api quand on est une nouvelle application, la seule solution est donc d’utiliser un display autre que wap et touch, il nous reste : popup et page, deux modes pour un écran desktop normalement, soit donc un affichage pas du tout adapté au mobile, mais bon, faute de mieux, on n’a pas le choix :

Donc si vous utilisez facebook SDK, n’oubliez pas d’utiliser :

parameters[“display”] = “popup”;

au lieu de

parameters[“display”] = “touch”;

De même le contrôle facebook de Bewise Phone Controls ne fonctionne plus (avec les nouvelles application facebook), si vous l’utilisez, remplacé :

  private const string loginURL = "https://graph.facebook.com/oauth/authorize?client_id={0}&redirect_uri=http://www.facebook.com/connect/login_success.html&skipcookie=1&display=touch&scope=publish_stream,user_hometown";

par

  private const string loginURL = "https://graph.facebook.com/oauth/authorize?client_id={0}&redirect_uri=http://www.facebook.com/connect/login_success.html&skipcookie=1&display=popup&scope=publish_stream,user_hometown";

Et si ça fonctionne actuellement pour moi ?

Si ton application a quelques semaines au moins, oui, tu ne rencontres pas ce soucis, car facebook ne te migrera qu’en juillet 2012.

Une option est normalement visible dans ton interface developers.facebook.com dans l’onglet “avancé” et est par défaut “désactiver”.

Ce qui signifie que le 1er juillet tu auras toi aussi la surprise d’avoir le message d’erreur si dessus si facebook ne pensent pas un peu à considérer notre plateforme d’ici là.

Lien vers le marketplace

Lien vers le marketplace

Une petite astuce, quand vous souhaitez partager un lien vers votre application, utilisez la syntaxe suivante :

http://www.windowsphone.com/s?appid=[ID]

à la place de :

http://www.windowsphone.com/fr-FR/apps/[ID]

Le site web de microsoft s’occupera de lui-même de vous rediriger vers la page correspondant à votre pays (et donc avec la description localisée).

Exemple pour Fuse :

http://www.windowsphone.com/s?appid=8355da61-1ac5-49cd-a753-7f6afed2bb62

Convertir un temps Unix vers un Datetime et inversement

Convertir un temps Unix vers un Datetime et inversement

Lorsque l’on utilise des services web, ils nous arrivent régulièremenet d’utiliser des Unix times que l’on souhaite ensuite manipuler comme des DateTime classique.

Qu’est ce qu’un Unix time ?

L’heure Posix (aussi appelée POSIX timestamp) est une mesure du temps utilisée principalement dans les systèmes qui respectent la norme POSIX, d’où son nom. Il s’agit du nombre de secondes écoulées depuis le 1er janvier 1970 00:00:00 UTC jusqu’à l’événement à dater.

Convertir un Unix Time vers un DateTime ?

Logiquement, on écrirait :

DateTime UnixTimeToDateTime(long unixTime)
{
return new DateTime(1970, 1, 1, 0, 0, 0).AddMilliseconds(unixTime);
}

Sauf qu’il y a deux erreurs dans ce code :

  • new DateTime(1970, 1, 1, 0, 0, 0) correspond au 1er Janvier 1970 de l’heure locale et non de l’heure UTC
  • On néglige les décalage horaires été/hiver

Il faut donc dans un premier temps récupérer le 1er janvier 1970 UTC, lui ajouter le nombre de secondes indiqué dans l’heure Posix puis enfin, convertir cette date en Local Time :

DateTime UnixTimeToDateTime(long unixTime)
{
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(unixTime).ToLocalTime();
}

Convertir un DateTime vers un temps Unix ?

Il suffit de transformer la date time en UTC de lui soustraire le 1er janvier 1970 et de récupérer

long ToUnixTime(this DateTime datetime)
{
TimeSpan ts = (datetime.ToUniversalTime() - new DateTime(1970, 1, 1,
0, 0, 0, DateTimeKind.Utc));
return (long)ts.TotalSeconds;
}

 

Attention

Certains services web vous envoie les dates Unix sous la forme de millisecondes voire parfois de tick, attention donc à bien les convertir en secondes auparavant.