Windows Phone 7.
Développez pour Windows Phone 7 en C# et Xaml. Cours complet
Publié le 19 octobre 2012
VI. Les différents contrôles
VI-A. Page
VI-B. Pivot et Panorama
VI-C. Les Conteneurs
VI-C-1. Les Grid
VI-C-2. Les StackPanel
VI-C-3. Les Canvas
VI-C-4. Les ScrollViewer
VI-C-5. WrapPanel
VI-C-6. Positionnement dynamique : les grandes règles
VI-D. Les Boutons
VI-D-1. Les 'Button'
VI-D-2. HyperLinkButton
VI-E. Les contrôles contenant du texte
VI-E-1. Les TextBlock
VI-E-2. Les TextBox
VI-E-3. Les RichTextBox
VI-E-4. Les PasswordBox
VI-F. Les cases à cocher et RadioButton
VI-F-1. Case à cocher
VI-F-2. RadioButton
VI-G. Les ListBox
VI-H. Les Slider
VI-I. Les MessageBox
VI-J. Image, Vidéo, Son
VI-K. Formes
VI-L. Barre System en haut
VI-M. Application Barre
VI-N. AdControl pour la publicité
VI-O. Le Toolkit
VI-P. MessageBox
VII. Grandes fonctions WP
VII-A. Données
VII-A-1. État de l'application
VII-A-2. Isolated Storage
VII-A-3. LINQ To SQL, données sur le Web
VII-B. Activation, désactivation, Tombstone.
VII-C. Le pattern Model-View-ViewModel
VII-D. Orientation
VII-E. Lanceur d'applications internes
VII-F. Les thèmes
VII-G. Vibreur
VII-H. Localisation
VII-I. Accéléromètre
VII-J. Internet, WebBrowser, WebClient
VII-K. Radio FM
VII-L. Minuterie
VII-M. Applications en tâche de fond : alarme, rappel
VII-N. Informations diverses
VI. Les différents contrôles
- Contrôles disponibles
Border
Button
Canvas
CheckBox
ContentControl
ContentPresenter
Control
Grid
HyperlinkButton
Image
InkPresenter
ListBox
MediaElement
MultiScaleImage
Panel
PasswordBox
ProgressBar
RadioButton
ScrollViewer
Slider
StackPanel
TextBlock
TextBox
Viewbox
UserControl
Border
Button
Canvas
CheckBox
ContentControl
ContentPresenter
Control
Grid
HyperlinkButton
Image
InkPresenter
ListBox
MediaElement
MultiScaleImage
Panel
PasswordBox
ProgressBar
RadioButton
ScrollViewer
Slider
StackPanel
TextBlock
TextBox
Viewbox
UserControl
Tous les contrôles ne sont pas disponibles dans la boîte à outils.
On peut si on le désire ajouter un contrôle dans la boîte à outils.
Dans celle-ci, clic droit sur 'Windows Phone Controls', puis dans le menu 'Choisir les éléments' et cocher un contrôle à ajouter dans la liste de la boîte à outils.

- Contrôles silverlight différents dans Windows Phone
ScroolBarr
ToolsTip
ComboBox
RichTextBox
ScroolBarr
ToolsTip
ComboBox
RichTextBox
- Ne sont pas disponibles dans Windows Phone
System.Windows.Controls.OpenFileDialog
System.Windows.Controls.SaveFileDialog
- Ne sont pas disponibles les contrôles qui sont dans le silverlight SDK
Calendar
ChildWindow
DataGrid
DatePicker
Frame
GridSplitter
Label
Page
TabControl
TreeView
On peut ajouter le ToolKit Silverlight for Windows Phone Toolkit pour Mango 7.1 : http://silverlight.codeplex.com/.
- Cela ajoute :
AutoCompleteBox
ContextMenu
DatePicker
GestureService/GestureListener
ListPicker
LongListSelector
Page Transitions
PerformanceProgressBar
TiltEffect
TimePicker
ToggleSwitch
WrapPanel
Il faut les ajouter à la boîte à outils. Voir le chapitre sur le Toolkit.
AutoCompleteBox
ContextMenu
DatePicker
GestureService/GestureListener
ListPicker
LongListSelector
Page Transitions
PerformanceProgressBar
TiltEffect
TimePicker
ToggleSwitch
WrapPanel
Il faut les ajouter à la boîte à outils. Voir le chapitre sur le Toolkit.
VI-A. Page
Une application très simple peut se composer d'une page principale (nommée 'MainPage' par défaut).
C'est le cas quand on crée une application en choisissant 'Application Windows Phone' :
C'est le cas quand on crée une application en choisissant 'Application Windows Phone' :

Ensuite on peut créer d'autres pages (menu 'Projet' puis 'Ajouter un nouvel élément').

Dans la page principale on peut ouvrir une autre page à l'aide du code suivant :
|
Quand on crée une page :
Elle est dans la Frame de l'application.
Cette Page contient une grille principale (nommée LayoutRoot).
Elle contient un StackPanel (nommé TitlePanel) comprenant le titre de l'application et le titre de la page.
Dessous il y une grille nommée ContentPanel dans laquelle il faudra mettre le contenu de la Page.
Elle est dans la Frame de l'application.
Cette Page contient une grille principale (nommée LayoutRoot).
Elle contient un StackPanel (nommé TitlePanel) comprenant le titre de l'application et le titre de la page.
Dessous il y une grille nommée ContentPanel dans laquelle il faudra mettre le contenu de la Page.
|
Une page fait 800 * 480 px. Le SystemTray en haut fait 32 px
(il peut y avoir des écrans de 480 * 320).
(il peut y avoir des écrans de 480 * 320).

Si on regarde le code C#, on constate que l'espace de noms est celui du projet (comme pour le code XAML) ; il y a une classe partielle 'MainPage' (la classe MainPage est donc composée du code XAML et de la classe partielle en C#).
|
Cette class MainPage hérite de la classe PhoneApplicationPage qui est la page standard.
Dans cette classe MainPage, il y a une fonction 'public MainPage()' qui est le constructeur de la page ; on y initialise les composants de la page ; on peut y ajouter du code qui sera exécuté lors de la création de la page.
Dans cette classe MainPage, il y a une fonction 'public MainPage()' qui est le constructeur de la page ; on y initialise les composants de la page ; on peut y ajouter du code qui sera exécuté lors de la création de la page.
Dans une page, on peut utiliser des évènements ; Loaded, par exemple.
Dans ce cas il faut ajouter 'Loaded=…'
Dans ce cas il faut ajouter 'Loaded=…'
|
Quand la page est chargée, la routine suivante, dans le code C#, est exécutée :
|
On verra qu'il est plus judicieux, pour mettre du code quand la page est chargée, d'utiliser une surcharge de OnNavigatedTo :
|
Il y a deux autres manières de structurer une application Windows Phone :
En utilisant le Pivot ou le Panorama.
En utilisant le Pivot ou le Panorama.
VI-B. Pivot et Panorama
Utilisons une page 'Pivot'.
C'est le cas quand on crée une application en choisissant 'Application Pivot Windows Phone' :

Voici un exemple de pages pivots :

Une application 'Pivot' contient plusieurs pages, on passe de l'une à l'autre en glissant horizontalement ou en tapant sur le nom grisé en haut de la page désirée.

Dans le code XAML on voit que le contrôle 'Pivot' contient des PivotItem ayant un titre (Header).
|
Code complet avec dans chaque PivotItem une ListBox :
|
Utilisons maintenant un 'Panorama'.
C'est le cas quand on crée une application en choisissant 'Application Panorama Windows Phone'.

Voici une page panorama :

Une application 'Panorama' contient une page unique très large, on se déplace en glissant horizontalement. Le titre est large et s'étale sur toute la grande page.
Le début du contenu de la page suivante de droite est légèrement visible.

Le contrôle Panorama contient des PanoramaItem ayant un titre (Header). Mis côte à côte les PanoramaItem forment la grande page virtuelle.
|
Code complet avec dans chaque PanoramaItem une ListBox :
|
VI-C. Les Conteneurs
Les conteneurs peuvent contenir plusieurs contrôles et permettent de les positionner.
VI-C-1. Les Grid
En silverlight une Grid est un conteneur, comprenant des cellules servant à aligner les contrôles (et pas une grille de données comme dans les Windows forms).
Aller chercher une 'Grid' dans la boîte à outils à gauche et la mettre sur la page.

|
On a une grille mais avec une seule cellule.
En fait quand on ajoute une page vide à un projet, la fenêtre contient déjà une Grid.
Comportement d'une 'Grid' a une seule cellule.
Ce n'est pas recommandé mais ajoutons deux TextBlock, une image et une ellipse dans la cellule unique :
Ce n'est pas recommandé mais ajoutons deux TextBlock, une image et une ellipse dans la cellule unique :
|
Cela donne :

On se rend compte que les éléments comme l'image et l'ellipse sont centrés et occupent le maximum de place.
Les TextBox sont placés en fonction de leur alignement.
Enfin on remarque que les éléments se superposent : l'ellipse qui est dans la dernière ligne du code XAML est au dessus.
Pour ajouter des lignes et des colonnes dans la grille (dans le designer), il faut cliquer dans les barres grises horizontales ou verticales de la grille et positionner les traits à la souris.

Cela génère le code XAML suivant :
|
On voit dans le code XAML les largeurs des colonnes (Grid.ColumnDefinition) et les hauteurs des lignes (Grid.RowDefinition).
On peut aussi vouloir définir le nombre de lignes et de colonnes sans définir leurs largeurs et hauteurs : simplement mettre trois lignes, deux colonnes.
|
Dans la définition des dimensions des lignes et colonnes :
on peut, comme on l'a vu, donner dans le designer la taille que l'on veut aux cellules.
Mais on peut, dans le code XAML, donner les dimensions des cellules :
- un chiffre ("150", par exemple) indique la largeur ou hauteur en pixels ;
- '*' signifie 'autant que possible' (cette ligne reçoit une proportion pondérée de l'espace disponible , 2* indiquant deux fois la proportion) ;
- 'Auto' force à prendre la taille des éléments qu'elle contient.
Mais on peut, dans le code XAML, donner les dimensions des cellules :
- un chiffre ("150", par exemple) indique la largeur ou hauteur en pixels ;
- '*' signifie 'autant que possible' (cette ligne reçoit une proportion pondérée de l'espace disponible , 2* indiquant deux fois la proportion) ;
- 'Auto' force à prendre la taille des éléments qu'elle contient.
Exemple de colonnes avec Auto :
|

Exemple de lignes avec des étoiles :
|

Si on fait :
|
On aura trois lignes d'égale hauteur et trois colonnes d'égale largeur. Cela donne neuf 'cellules' carrées.
On peut rendre les lignes de séparation visibles :
|
On peut ensuite ajouter des contrôles dans les cellules de la grille pour les positionner.
Pour chaque contrôle ajouté dans une cellule de la Grid, on définira la cellule où le contrôle se trouve, ses marges et son ancrage si nécessaire.
Ici on va ajouter une ListBox en bas à droite de la grille, voyons ce que cela donne dans le code XAML.
|
ListBox Grid.Column="3" Grid.Row="2" indiquent dans quelle cellule est la ListBox.
Attention la première colonne est Column=0 et la première ligne est Row=0.
On aurait pu ajouter Grid.ColumnSpan=2 pour indiquer que la ListBox occupe deux colonnes (la 3 et la 4 dans ce cas).
Il existe aussi Grid.RowSpan pour étendre le contrôle sur plusieurs lignes de la Grid.
On aurait pu ajouter :
Margin="22,26,21,19" pour indiquer les distances au conteneur autour de la ListBox.
Comment faire la même chose en C# ?
La Grid1 étant présente, ajoutons une ListBox comme ci dessus :
La Grid1 étant présente, ajoutons une ListBox comme ci dessus :
|
VI-C-2. Les StackPanel
Arrange, empile les contrôles sur une même ligne qui peut être horizontale ou verticale (on parle d'empilement).
En C# :
|
En XAML :
|
On a ajouté dans le StackPanel trois boutons.
En XAML :
|
On voit qu'il suffit de mettre les objets dans le StackPanel, ils seront empilés.

La valeur par défaut de Orientation du StackPanel est Vertical, aussi les contrôles seront positionnés de haut en bas.
L'attribut Orientation="Horizontal" permet de mettre les contrôles enfants de gauche à droite.

|
C'est bien pratique quand on veut mettre sur une même ligne, les différents champs d'un objet (nom, prénom, adresse) :
|
En C#, voici un autre exemple :
|
On a instancié des boutons que l'on ajoute à la collection Children du StackPanel.
Enfin, on met donc le StackPanel dans une grille nommée ContentPanel.
On peut insérer un bouton3 supplémentaire à une position définie :
|
Le bouton2 est automatiquement repositionné.
VI-C-3. Les Canvas
Il existe un contrôle Canvas qui permet de positionner des contrôles en indiquant leurs coordonnées (comme dans les Windows Forms), mais il n'y a pas de repositionnement automatique quand on modifie les dimensions du Canvas.
On positionne les contrôles avec les propriétés attachés Canvas.Top et Canvas.Left qui se trouvent dans le contrôle enfant.

En XAML :
|
Les Canvas ont une propriété attachée ZIndex permettant d'imposer l'ordre de superposition des éléments enfants (syntaxe dans l'élément enfant : Canvas.ZIndex="2").
VI-C-4. Les ScrollViewer
Représente une zone défilante qui peut contenir d'autres éléments visibles bien plus grands ; on fait défiler le contenu qui est dans le ScrollViewer au doigt, il apparaît des ScrollBarr si nécessaire.
Une utilisation habituelle est de mettre dans un petit ScrollViewer qui utilise la place disponible, un grand TextBlock, contenant un long texte.

|
HorizontalScrollBarVisibility et VerticalScrollBarVisibility permettent de forcer ou non l'affichage de la ScrollBarr ; ici il est à 'Auto'.
Voici comment on positionne le ScrollViewer (qui reste sur l'écran) et le TextBlock interne (plus grand que l'écran) dans le designer :

Le ScrollViewer peut aussi être utilisé comme conteneur de tous les objets de la page ; si on passe en mode paysage les objets du bas de la page ne sont plus visibles mais on peut remonter la page pour en voir le bas.
VI-C-5. WrapPanel
Le WrapPanel qui est un conteneur où les éléments sont mis à la suite l'un de l'autre mais où il y a "retour à la ligne" quand on atteint la limite du conteneur.
Les éléments se positionnent de gauche à droite et de haut en bas.
Voir le chapitre sur le Toolkit.
Voir le chapitre sur le Toolkit.
VI-C-6. Positionnement dynamique : les grandes règles
Layout dynamique : permet un positionnement quel que soit la résolution de l'écran.
On utilise un StackPanel ou surtout une Grid comme conteneur.
Dans les cellules, on met des contrôles avec les propriétés Width et Height= Auto. Ils occupent toutes la cellule (Margin permet de laisser un espace autour).
S'il y a un texte à afficher en totalité on donne une valeur à MinHeight et MinWidth pour que le texte ne soit pas tronqué.
On donne des dimensions relatives pour les colonnes et les lignes de la Grid (dans RowDefinition et ColumnDefinition) à l'aide des *.
On utilise un StackPanel ou surtout une Grid comme conteneur.
Dans les cellules, on met des contrôles avec les propriétés Width et Height= Auto. Ils occupent toutes la cellule (Margin permet de laisser un espace autour).
S'il y a un texte à afficher en totalité on donne une valeur à MinHeight et MinWidth pour que le texte ne soit pas tronqué.
On donne des dimensions relatives pour les colonnes et les lignes de la Grid (dans RowDefinition et ColumnDefinition) à l'aide des *.
VI-D. Les Boutons
VI-D-1. Les 'Button'
Pour ajouter un bouton, on clique sur le bouton dans les outils à gauche puis sur le formulaire, on appuie (bouton gauche de la souris), on déplace puis on lâche. Le bouton apparaît.

En bas à droite, on a la fenêtre de propriétés du bouton.
Le nom du contrôle est en haut, après 'Name'.
Dans le designer, la propriété 'Content' contient le texte à afficher sur le bouton.
Si on double-clique sur un bouton, par exemple, on se retrouve dans la fonction évènement correspondante qui est Button1_Click.
Créons un bouton avec du code XAML.
Il faut taper dans la fenêtre XAML :
|
Cela crée un bouton sur lequel est affiché 'Ok'. Il apparaît en haut.
Faisons plus complet :
|
Voyons le détail de cette ligne :
La balise 'Button' crée un bouton.
Name="Button1" indique le nom du contrôle dans le designer.
VerticalAlignment="Top" indique que le contrôle est ancré en haut (il reste toujours à la même distance du bord sur lequel il est ancré. Valeur possible : Top, Bottom, Center.
HorizontalAlignment="Left" même chose pour l'alignement horizontal.
Margin définit la distance par rapport aux bords du conteneur.
Width="" Height="" indiquent les dimensions du bouton (largeur, hauteur).
On peut aussi ajouter MinWidth MinHeight MaxWidth et MaxHeight qui indiquent les tailles minimales et maximales.
On aurait pu utiliser l'attribut Content="Ok" pour mettre un texte dans le bouton.
On peut positionner le 'Content' dans le bouton en indiquant des alignements et marges internes (Padding) :
On peut positionner le 'Content' dans le bouton en indiquant des alignements et marges internes (Padding) :
|
Click="OnClick5" indique que l'action de cliquer sur le bouton déclenche la fonction OnClick5.
Cela crée automatiquement, dans le code C#, la routine suivante :
|
sender est l'objet qui a déclenché l'évènement.
e contient les arguments de l'évènement, remarquons que e est de type RoutedEventArgs (et pas EventArgs comme dans les Windows Forms).
On peut ajouter du code dans la routine, pour modifier les propriétés du bouton, par exemple :
|
Mettre des formes dans un bouton puis y mettre une image.
|
Cela donne :

Pour mettre une image dans un bouton il faut avoir le fichier image, l'ajouter au projet (menu 'Projet' puis 'Ajouter un élément existant') ajouter Image et renseigner la source.
On peut choisir un fichier GIF avec un fond 'transparent' ce qui permet de ne pas voir le fond de l'image.
Comment mettre un texte et une image dans un bouton ?
Il faut mettre un StackPanel dans le bouton (puisque celui-ci ne peut contenir qu'un seul objet), dans ce StackPanel mettre un TextBlock et une Image. Le faire en tapant du code XAML (dans le designer VB c'est difficile de mettre un StackPanel dans un Button, il se met dessus et pas dedans, donc copier/coller le code XAML). De plus l'image doit être dans les ressources.
|
Cela donne :

Voir aussi le chapitre sur les ressources.
Créons un bouton avec du code C# :
|
On remarque que, comme on crée par code, il faut soi même écrire la gestion des évènements.
Quand on crée le bouton en mode designer, et que l'on double-clique sur le bouton, la routine myButton_Click est automatiquement affichée.
VI-D-2. HyperLinkButton
Représente un bouton qui affiche un lien hypertexte.
|

NavigateUri donne l'adresse.
TargetName a la valeur :
_blank, _media ou _search, cela charge le document dans une nouvelle fenêtre vide.
_parent, _self, _top, ou "" cela charge la page dans la fenêtre dans laquelle l'utilisateur a cliqué sur le lien (la fenêtre active).
L'effet n'est pas visible.
TargetName a la valeur :
_blank, _media ou _search, cela charge le document dans une nouvelle fenêtre vide.
_parent, _self, _top, ou "" cela charge la page dans la fenêtre dans laquelle l'utilisateur a cliqué sur le lien (la fenêtre active).
L'effet n'est pas visible.
Si on met une adresse Internet, cliquer sur le lien ouvre le navigateur Web.
On peut aussi naviguer vers une autre page :
|
VI-E. Les contrôles contenant du texte
Les contrôles permettant de voir ou de modifier du texte sont :
- les TextBlock ;
- les TextBox ;
- les RichTextBox ;
- les PasswordBox.
VI-E-1. Les TextBlock
Permettent d'afficher du texte dans une page en lecture seule, sans possibilité de le modifier. Il est bien adapté pour afficher une ou au maximum quelques lignes.
Prendre un TextBlock dans les outils et le mettre dans un formulaire.

Pour mettre rapidement un petit texte dedans en C#, utiliser la propriété Text.
|
La même chose en XAML :
|
|
Permet de passer automatiquement à la ligne.
On peut modifier le texte (Text), la hauteur des caractères (FontSize), la couleur du texte (Foreground) :
|

Un TextBlock a une propriété Foreground (couleur du texte) mais pas de Background (pas de couleur de fond), pas de bords.
Pour mettre une couleur de fond, il faut mettre le TextBlock dans un Rectangle.
Pour avoir un bord, mettre le TextBlock dans un Border (dans le TextBox mettre Margin="0").
Pour avoir un bord, mettre le TextBlock dans un Border (dans le TextBox mettre Margin="0").
|
On peut ajouter des sauts de lignes simplement grâce à \n.
|
On peut ajouter dans le code XAML plusieurs lignes (avec la balisee 'Run' qui correspond à un morceau de texte) avec des couleurs, des tailles, des polices différentes et des retours à la ligne avec des LineBreak.
|

On peut le faire en C# :
|
|
On déclare un 'Run', on modifie ses propriétés ; on l'ajoute à la collection de lignes (InLines). On peut aussi ajouter un saut de ligne.
Exercice : j'ai une string mySting, je veux l'ajouter à un TextBlock avec des passages à la ligne et mettre la première ligne en orange.
|
J'ai ajouté un caractère '¤' signifiant retour à la ligne.
Je vais découper la string grâce à Split puis avec une boucle je vais ajouter à la collection InLines un Run (un texte ) puis un LineBreak.
Je vais découper la string grâce à Split puis avec une boucle je vais ajouter à la collection InLines un Run (un texte ) puis un LineBreak.
|
VI-E-2. Les TextBox
Permettent d'afficher du texte, il est modifiable par l'utilisateur.
La police de caractères, sa taille, la couleur, l'enrichissement des caractères affectent la totalité du texte. Il n'est pas possible d'enrichir (gras, italique…) une partie du texte seulement.

Créons un TextBox en XAML :
|
Donnons lui un nom :
|
Mettons un texte dedans :
|
En C#
|
TextBox1.Text contient le texte affiché dans la TextBox.
TextBox1.IsReadOnly=true interdit les modifications du texte.
TextBox1.AcceptEnter=true autorise le passage à la ligne quand on tape 'Enter'. Si AcceptEnter=false, on ne peut saisir qu'une seule ligne.
VerticalScrollBarVisibility=true affiche une ScrollBar verticale.
TextBox1.MaxLength permet de définir le nombre de caractères. 0 pour une saisie illimitée.
Si l'utilisateur a sélectionné du texte, il est dans TextBox1.SelectedText.
TextBox1.SelectionStart, TextBox1.SelectionLength indique la position du premier caractère sélectionné (le premier caractère du texte étant le caractère 0) et le nombre de caractères sélectionnés.
On peut utiliser ces propriétés pour sélectionner du texte avec du code ou utiliser TextBox1.Select(3, 2), il existe enfin SelectAll qui selectionne la totalité du texte.
On peut utiliser ces propriétés pour sélectionner du texte avec du code ou utiliser TextBox1.Select(3, 2), il existe enfin SelectAll qui selectionne la totalité du texte.
Si le texte est modifié cela déclenche :
|
Double_cliquez sur le TextBox, cela fera apparaître le code qui précède.
Quand l'utilisateur frappe une touche cela déclenche les évènements KeyDown puis KeyUp (pas de keyPress !)
Pour ajouter la gestion de l'évènement KeyUp, cliquer sur le bouton. Dans la fenêtre des propriétés cliquer sur l'onglet 'Évènements'.

Puis dans la liste double-cliquez sur 'KeyUp' vous voyez apparaître :
|
Et dans le code C# :
|
On note que la fonction a un paramètre e de type KeyEventArgs qui a la propriété Key qui contient la touche tapée. Malheureusement e.Key est en lecture seule ! On ne peut donc pas modifier le caractère tapé !
De plus le contenu de e.Key est bizarre ! Des expressions comme if (e.Key==Key.B)… ne fonctionnent pas car e.Key ne contient pas ce qui est attendu.
De plus le contenu de e.Key est bizarre ! Des expressions comme if (e.Key==Key.B)… ne fonctionnent pas car e.Key ne contient pas ce qui est attendu.
Pour modifier les caractères tapés on les modifie directement dans la propriété text :
|
Quand on tape sur une TextBox et qu'elle prend le focus, il apparaît automatiquement un clavier virtuel en bas.
Le clavier par défaut, si on n'indique rien est le clavier "Default".
Il permet de taper des minuscules et donne accès aux majuscules et aux chiffres :
Le clavier par défaut, si on n'indique rien est le clavier "Default".
Il permet de taper des minuscules et donne accès aux majuscules et aux chiffres :

Ce petit clavier à l'écran est appelé "panneau de saisie logiciel" ou SIP.
Mais on peut avoir besoin d'afficher un autre clavier virtuel.
Voici le clavier TelephoneNumber permettant de taper des numéros de téléphone :
Voici le clavier TelephoneNumber permettant de taper des numéros de téléphone :

Comment l'obtenir ?
En utilisant un InputScope.
En utilisant un InputScope.
|
Ci dessous une syntaxe plus longue mais permettant d'avoir de l'aide à la saisie, la liste des valeurs s'affiche quand on saisit NameValue :
|
En C# :
|
Il y a aussi DateDay, DateMonth, DateYear, Address, Chat, Digits, FileName, Number, OneChar, PostalCode, Text, Time, Url, Xml…
Voici quelques exemples :
Voici quelques exemples :
Text :
la première lettre tapée est en majuscule puis le clavier passe en minuscules.
Quand on tape au moins une lettre la zone au dessus du clavier propose des mots sur lesquels on peut taper.
En plus de ces suggestions de texte, il y a la correction automatique, l'auto-apostrophe, l'auto-accentuation et l'auto capitalisation.
Chat est le même clavier (contrairement à la version anglaise et a ce qui est dit par ailleurs).
Quand on tape au moins une lettre la zone au dessus du clavier propose des mots sur lesquels on peut taper.
En plus de ces suggestions de texte, il y a la correction automatique, l'auto-apostrophe, l'auto-accentuation et l'auto capitalisation.
Chat est le même clavier (contrairement à la version anglaise et a ce qui est dit par ailleurs).

Url :
permet de saisir des adresses Internet.
L'appui long sur '.com' donne accès à d'autres nom de domaine.

Digit :
pour saisir les chiffres de 0 à 9 et le point (même si on est en clavier français).
CurrencyAmmont et Number sont le même clavier en français.

CurrencyAmountAndSymbol :
permet de saisir chiffres et symboles.

![]() |
Contrairement à ce qui est dit ailleurs les inputscope sont différents de ceux de la version anglaise. Sous Mango, l'InputScope 'Number', représente maintenant uniquement un clavier numérique, alors qu'auparavant c'était le clavier chiffre+symboles. |
En cours de saisie, il ne faut pas oublier de filtrer les caractères tapés (voir chapitre 'Comment faire').
VI-E-3. Les RichTextBox
Rich Text veut dire 'Texte enrichi.'
Le contrôle RichTextBox permet d'afficher, d'entrer et de manipuler du texte mis en forme. Il effectue les mêmes tâches que le contrôle TextBox, mais il peut également afficher des polices, des couleurs pour une partie du texte et des liens, charger du texte et des images incorporées à partir d'un fichier, ainsi que rechercher des caractères spécifiques.
Le contrôle RichTextBox permet d'afficher, d'entrer et de manipuler du texte mis en forme. Il effectue les mêmes tâches que le contrôle TextBox, mais il peut également afficher des polices, des couleurs pour une partie du texte et des liens, charger du texte et des images incorporées à partir d'un fichier, ainsi que rechercher des caractères spécifiques.
![]() | En Wp RichTextBlox est ReadOnly, donc pas de possibilité d'écrire dedans ! ce qui lui enlève son intérêt. |
Ce contrôle n'apparaît pas dans la liste d'outils ; il faut l'ajouter :
Dans la boîte à outils, clic droit sur 'Windows Phone Controls', puis clic sur la ligne 'Choisir les éléments'.

Là on peut cocher le contrôle 'RichTextBox' à ajouter dans la liste de la boîte à outils.
En XAML :
on peut ajouter un texte dans la balise Paragraph, l'enrichir avec les balises Bold, Italic, Underline, Hyperlink.
On peut aller à la ligne avec LineBreak.
on peut ajouter un texte dans la balise Paragraph, l'enrichir avec les balises Bold, Italic, Underline, Hyperlink.
On peut aller à la ligne avec LineBreak.
|

Noter la syntaxe du lien qui montre que dans la balise on peut ajouter des attributs.
On va voir un autre exemple avec un Border et l'utilisation d'attributs pour modifier la couleur et la taille des caractères :
On va voir un autre exemple avec un Border et l'utilisation d'attributs pour modifier la couleur et la taille des caractères :
|
Cela donne :

En C# c'est un peu plus difficile :
On crée des 'Run' (portion de texte) qu'on met dans la collection Inlines des 'Paragraph'. Ensuite on met les paragraphes dans la collection Blocks du RichTextBox.
|
VI-E-4. Les PasswordBox
Permet de saisir un mot de passe.
La propriété PasswordChar détermine le caractère affiché à la place des caractères tapés.
En XAML :
|
Ici le fait de taper un mot de passe déclenche la fonction PasswordChanged.
En C# on récupère le mot de passe dans :
|
VI-F. Les cases à cocher et RadioButton
VI-F-1. Case à cocher

Créons une case à cocher.
C'est une CheckBox. L'utilisateur peut la cocher ou non en cliquant dessus.
Dans le designer, la propriété Content contient le texte à afficher à côté de la case.
Les évènements les plus utiles sont : Checked et Unchecked.
|
|
Dans le code XAML IsChecked="True" permet de cocher un CheckBox.
Dans le code C#, la propriété IsChecked permet de voir si la case est cochée ou non.
|
VI-F-2. RadioButton
Les RadioButton peuvent être cochés ou non.

Ils sont généralement regroupés pour offrir aux utilisateurs un choix unique parmi plusieurs options, un seul bouton à la fois peut être coché. Si on clique sur un RadioButton dans un groupe, on le sélectionne, cela désélectionne les autres.
Vous pouvez regrouper des contrôles RadioButton en les plaçant dans un parent commun ou en leur attribuant un nom de groupe (GroupName).
Quand un RadioButton est sélectionné, l'événement Checked est déclenché. Comme le montre l'exemple de code suivant, si votre application doit faire une action quand la sélection de RadioButton change, vous pouvez gérer l'événement Checked.
|
VI-G. Les ListBox
Une ListBox est un contrôle qui contient une collection de ListBoxItem. Chaque ListBoxItem a une propriété 'Content'.
Créons une ListBox avec trois ListBoxItem en XAML :
|

Créer en C# une ListBox puis ajouter des éléments à la ListBox :
|
On peut créer en C#, une collection 'Villes', y ajouter des éléments et ensuite faire un binding :
|
Dans ce cas dans le code XAML ItemsSource doit indiquer qu'il y a binding.
|
On peut effacer la liste.
|
SelectedIndex indique l'index de l'élément sélectionné (-1 si pas de sélection).
SelectedItem indique l'item (objet) sélectionné. On peut l'utiliser pour forcer par code la sélection.
SelectedItem indique l'item (objet) sélectionné. On peut l'utiliser pour forcer par code la sélection.
|
On peut ajouter un bord autour du ListBox :
|
Maintenant on veut personnaliser chaque Item.
Pour cela, on va utiliser un style pour les ListBoxItem.
On va créer dans les ressources de la grille racine un style pour les ListBoxItem ; ce style définira un template qui affiche un bord pour chaque Item.
Enfin on créera la ListBox en utilisant pour chaque ListBoxItem le style précédent.
Pour cela, on va utiliser un style pour les ListBoxItem.
On va créer dans les ressources de la grille racine un style pour les ListBoxItem ; ce style définira un template qui affiche un bord pour chaque Item.
Enfin on créera la ListBox en utilisant pour chaque ListBoxItem le style précédent.
|
On remarque que le Template du ListBoxItem contient dans le Border un ContentPresenter ; dans ce ContentPresenter, on indique que le Content doit être lié au content du ListBoxItem.

On peut aussi modifier l'item template pour, au lieu d'afficher les items les uns au dessus des autres, les afficher de gauche à droite avec passage à la ligne (comme dans le Media Library). Il faut pour cela utiliser un WrapPanel (voir dans le chapitre sur le Toolkit).
Mettre des boutons, des cases à cocher dans une ListBox :
Les CheckedListBox n'existent pas en WP ? On va les créer dans une ListBox1 :
|

De la même manière, on peut créer une liste de boutons…
Utilisation du binding sur une ListBox.
On reprend l'exemple du chapitre sur le binding en le complétant.
Dans Class1.cs on crée une classe nommée 'ElementDeListe'.
Dans Class1.cs on crée une classe nommée 'ElementDeListe'.
|
Dans MainPage.xaml.cs on déclare une Collection nommée 'ListMath' de type List, on y met quelques éléments.
|
En fin de code on lie la collection à la ListBox grâce à sa propriété DataContext.
Dans MainPage.xaml on crée une ListBox nommée 'listBox1', on indique que la source des items est une liaison.
|
Cela donne :

La ListBox affiche les types !
C'est normal elle affiche ce que retourne la méthode ToString().
C'est normal elle affiche ce que retourne la méthode ToString().
On a une première méthode pour éviter l'affichage du type : on surcharge la méthode ToString de la classe ElementdeListe :
|
Cela marche bien mais uniquement avec du texte.
Une autre méthode (plus générale) pour afficher Titre et Formule, on va ajouter un ItemTemplate contenant un StackPanel horizontal qui contient trois TextBlock. Le premier et le troisième sont liés au propriétés 'Titre' et 'Formule'.
|

Utilisation d'ItemTemplate complexe.
On veut afficher pour chaque Item une petite sphère, la propriété 'Titre' en gros et la propriété'Formule' dessous en plus petit :
|

![]() | Bien respecter les majuscules et minuscules dans les liaisons car si on se trompe d'une lettre, rien ne signale une erreur mais cela ne marche pas. |
On voit que l'ItemTemplate est beaucoup plus puissant, on peut afficher dans la ListBox du texte mais aussi des images…
Et les évènements !
Il est indiqué partout d'utiliser l'évènement SelectionChanged :
|
Ainsi quand l'utilisateur tape sur une ligne de la ListBox l'évènement SelectionChanged se produit et la routine suivante est exécutée.
|
L'inconvénient est que si je tape deux fois de suite sur le même item de la ListBox, la seconde fois ne déclenche rien puisque la sélection n'a pas changé.
J'utilise plutôt MouseLeftButtonUp.
|
Quand l'utilisateur tape sur une ligne de la ListBox l'évènement MouveLeftButtonUp se produit et la routine suivante est exécutée.
Je peux utiliser l'item sélectionné : SelectedItem.
Je peux utiliser l'item sélectionné : SelectedItem.
|
VI-H. Les Slider
Un Slider est un curseur qu'on peut déplacer avec le doigt :
|
Ici on utilise un Slider pour modifier la hauteur d'un rectangle grâce au binding.

VI-I. Les MessageBox
Comment afficher un message pour l'utilisateur (sans sortir de la page) ?
|
Cela donne :

Il y a un bouton 'Ok' par défaut pour sortir du MessageBox.
Sinon on peut ajouter un titre et un bouton 'Annuler'.
|

MessageBox peut retourner dans une variable de type MessageBoxResult le résultat de l'action de l'utilisateur :
A-t-il tapé sur Ok ou Annuler ?
MessageBoxResult.Ok
ou
MessageBoxResult.Cancel
sera retourné suivant le bouton qui a été tapé par l'utilisateur.
|
En WP7 il n'y a que deux boutons possibles.
Les InputBox n'existent pas.
VI-J. Image, Vidéo, Son
On peut ajouter un contrôle 'Image'.
Comment mettre une image dans un contrôle image ?
En C# :
(image qui est sur Internet puis image locale) :
En C# :
(image qui est sur Internet puis image locale) :
|
Dans le code XAML :
|
Ici l'image (option de génération = Contenu) est dans un répertoire 'Images' du projet.
Si l'image n'existe pas, il n'y a pas de levée d'exception. Pas d'arrêt du logiciel avec un code d'erreur. Cool !
Par contre, si on veut, on peut intercepter l'erreur en 's'abonnant' à l'évènement ImageFailed.
L'image doit être mise dans le projet : menu 'Projet', 'Ajouter un élément existant', choisir l'image puis 'Ok', elle apparaît dans la fenêtre de l'explorateur de solution à droite.
Dans ses propriétés en bas à droite, il faut mettre 'Option de génération" à 'Contenu' ou le laisser à 'Resource' (et Copier… à 'Copier si plus récent').
On se souvient que le chemin de l'application est 'C:\Users\Philippe\Documents\Visual Studio 2010\Projects\Mon application'.
Utiliser des fichiers JPEG plutôt que des PNG (le décodage des PNG se fait au niveau logiciel alors que celui des JPEG se fait au niveau matériel).
Par contre pas de transparence dans les JPEG.
Pas de GIF dans WP.
Par contre pas de transparence dans les JPEG.
Pas de GIF dans WP.
On peut donner un chemin absolu :
|
On peut aussi utiliser les ressources pour mettre l'image (voir chapitre Ressources).
On peut ajouter l'attribut Opacity dont la valeur va de 0 à 1.
|
L"image est semi-transparente.
L'attribut Stretch permet de gérer les dimensions de l'image ; par défaut elle a la valeur 'Uniform', ainsi la totalité de l'image rentre dans le contrôle sans déformation.
'UniformToFill' conserve les proportions mais ne force pas la totalité de l'image a être affichée.
'UniformToFill' conserve les proportions mais ne force pas la totalité de l'image a être affichée.
'Fill' adapte l'image au conteneur, mais il peut y avoir des déformations.
'None' respecte les dimensions en pixel de l'image, l'image peut être plus petite ou plus grande que le conteneur ; on peut ne pas la voir en totalité.
'None' respecte les dimensions en pixel de l'image, l'image peut être plus petite ou plus grande que le conteneur ; on peut ne pas la voir en totalité.
|
StretchDirection = UpOnly ne permet que l'agrandissement, DownOnly permet le contraire. Par défaut sa valeur est égale à Both.
On peut appliquer une transformation à une image (ici une rotation de 90 degrés) :
|
Pour le son, la vidéo : on peut lire des Windows Media Video (WMV), Windows Media Audio (WMA), et fichier MP3.
|
On peut arrêter, mettre en pause, démarrer une vidéo :
|
On peut ajouter une propriété 'Volume' avec une valeur allant de 0 à 1 (défaut=0.5) en échelle logarithmique.
On peut aussi ajouter une propriété 'AutoPlay', elle est à true par défaut. Il y a aussi Stretch et IsMuted.
VI-K. Formes
Le rectangle
|

Fill : couleur de remplissage.
Stroke : couleur du bord.
StrokeThickness : épaisseur du bord.
RadiusX et RadiusY : arrondir les angles.
Stroke : couleur du bord.
StrokeThickness : épaisseur du bord.
RadiusX et RadiusY : arrondir les angles.
L'ellipse
exemple : une sphère, on remplit un cercle (une ellipse aussi haute que large) avec un RadialGradientBrush :
|

On peut ajouter un bord autour d'un conteneur (ou d'un contrôle) :
|
L'attribut CornerRadius permet d'arrondir les angles.
Voici un exemple en code c# :
|
On remarque que pour modifier le bord, le tour de la forme, on utilise Stroke (couleur) et StrokeThickness (épaisseur).
Polygone
On définit des points, il y a une ligne entre un point et le suivant, le dernier point étant relié au tout premier.
On définit des points, il y a une ligne entre un point et le suivant, le dernier point étant relié au tout premier.
|

Il y a une collection 'PointCollection' dans lequel vous ajoutez les 'Point' pour former la collection.
Polylines fait de même sauf que le dernier point n'est pas relié au premier.
Path (chemin)
Permet de dessiner un chemin complexe :
Permet de dessiner un chemin complexe :
|
Data contient :
M : coordonnées (absolu) du point de départ ('m' si coordonnées relative) ;
C : courbe de Bézier commençant à la position de départ, se terminant à 400, 175 (2 dernières valeurs) ;
Passant pas les points 100,25 et 400,350 ;
V : ligne vertical se terminant à l'ordonnée 140 ;
H : ligne horizontale se terminant à l'abscisse 140.
M : coordonnées (absolu) du point de départ ('m' si coordonnées relative) ;
C : courbe de Bézier commençant à la position de départ, se terminant à 400, 175 (2 dernières valeurs) ;
Passant pas les points 100,25 et 400,350 ;
V : ligne vertical se terminant à l'ordonnée 140 ;
H : ligne horizontale se terminant à l'abscisse 140.

Exemple plus complexe : dans un bouton, dessiner une loupe, l'agrandir grâce à RenderTransform :
|

Line
Elle va du point X1,Y1 à X2,Y2.
Elle va du point X1,Y1 à X2,Y2.
En XAML :
|
En C# :
|
VI-L. Barre System en haut
Le SystemTray est la bande en haut qui contient les icônes de charge, de réseau, de type de réseau, l'heure.

Elle fait 32 pixels en vue portrait et 72 pixels en vue paysage. En mode paysage la barre est sur le rebord gauche de l'écran et pas en haut.
Par défaut, elle est blanche ou noire en fonction du thème. La grille 'LayoutRoot' commence dessous.
Par défaut, elle est blanche ou noire en fonction du thème. La grille 'LayoutRoot' commence dessous.
Dans le XAML, dans la balise 'PhoneApplicationPage', on charge l'espace de noms 'Microsoft.Phone.Shell' (il l'est pas défaut).
Puis on peut modifier le SystemTray.
On peut ne pas afficher le SystemTray.
|
Il est possible de modifier la couleur des icônes et du fond.
Cela ne marche qu'à partir de WP7.1 (Mango).
|
Il y a un bug et pour mettre du blanc il faut écrire : shell:SystemTray.ForegroundColor="#FEFEFE".
On peut modifier l'opacité (de 0 à 1).
|
L'opacité n'a pas d'incidence sur les icônes.
Si on modifie l'opacité, la page débute sur le bord de l'écran (en arrière du SystemTray) on voit donc la page par transparence à travers le SystemTray.
Si on modifie l'opacité, la page débute sur le bord de l'écran (en arrière du SystemTray) on voit donc la page par transparence à travers le SystemTray.

Sinon la page débute en dessous du SystemeTray.

En C# on peut modifier l'opacité de la bande (0 à 1) et les couleurs :
|
Ici on indique la page en premier paramètre.
Il existe aussi GetIsVisible… pour lire la propriété.
Il existe aussi GetIsVisible… pour lire la propriété.
Quand on a un arrière fond clair et si on a modifié la taille de la Grid LayoutRoot, cela fait une bande blanche en haut ; pour éviter cela, il ne faut pas afficher le System Tray et surtout ne pas donner de hauteur à la grille, ainsi elle occupera tout l'espace (on peut donner, sans le vouloir, une valeur en déplaçant par erreur la grille) :
|
On peut aussi ajouter un ProgressIndicator.
Si IsIndeterminate = true cela affiche les points qui bougent de gauche à droite.
Si IsIndeterminate = false cela affiche une barre rouge de gauche à droite. La valeur de 'Value' donne donne la longueur de la barre : 0= pas de barre, 1= barre complète.
Si IsIndeterminate = true cela affiche les points qui bougent de gauche à droite.
Si IsIndeterminate = false cela affiche une barre rouge de gauche à droite. La valeur de 'Value' donne donne la longueur de la barre : 0= pas de barre, 1= barre complète.
|

VI-M. Application Barre
L'application Barre permet de mettre une barre en bas avec des icônes (quatre maximum) et même d'ajouter un menu qu'on ouvre (avec les trois petits points).
Le code de l'ApplicationBar est déjà donné par Microsoft (il est en commentaire en bas de la page), j'ai ajouté la gestion des clics.
Le code de l'ApplicationBar est déjà donné par Microsoft (il est en commentaire en bas de la page), j'ai ajouté la gestion des clics.
|
|

L'option de génération des fichiers images doit avoir la valeur 'Contenu' et l'option 'Copier dans…' la valeur 'Copier si plus récent'.
Les icônes n'apparaîssent pas dans l'IDE, il faut tester avec l'émulateur.
On peut trouver des icônes dans le SDK, ici "C:\Program Files\Microsoft SDKs\Windows Phone\v7.1\Icons\dark", utiliser uniquement le répertoire dark, WP se chargera d'adapter l'image au thème.
On peut en trouver aussi sur Internet ou les dessiner soi-même. Microsoft conseille des images de 48 x 48 px avec le fond graphique au centre de 26 x 26 px. Couleur d'avant plan blanche et fond transparent ; pas de cercle qui sera dessiné par WP sur le bouton.
Les icônes n'apparaîssent pas dans l'IDE, il faut tester avec l'émulateur.
On peut trouver des icônes dans le SDK, ici "C:\Program Files\Microsoft SDKs\Windows Phone\v7.1\Icons\dark", utiliser uniquement le répertoire dark, WP se chargera d'adapter l'image au thème.
On peut en trouver aussi sur Internet ou les dessiner soi-même. Microsoft conseille des images de 48 x 48 px avec le fond graphique au centre de 26 x 26 px. Couleur d'avant plan blanche et fond transparent ; pas de cercle qui sera dessiné par WP sur le bouton.
Si on veut désactiver le second bouton dans le code-behind :
|
VI-N. AdControl pour la publicité
À partir de Mango, on peut ajouter dans une application de la publicité rémunérée proposée par Microsoft.
Aller sur https://pubcenter.microsoft.com pour s'inscrire.
Une fois inscrit vous devrez choisir la taille de votre bannière (480*80 ou 300*50) et vous obtiendrez deux identifiants (ApplicationId et AdUnitId).
Aller sur https://pubcenter.microsoft.com pour s'inscrire.
Une fois inscrit vous devrez choisir la taille de votre bannière (480*80 ou 300*50) et vous obtiendrez deux identifiants (ApplicationId et AdUnitId).
À partir de la boîte à outils glisser/déposer un contrôle AdControl :

Cela donne dans l'XAML :
|
Bien mettre les Id récupérés sur le site.
Le contrôle ici a une taille de 480*80.
Il est impératif de respecter la taille et de ne pas modifier l'opacité.
Le contrôle ici a une taille de 480*80.
Il est impératif de respecter la taille et de ne pas modifier l'opacité.
VI-O. Le Toolkit
Le silverlight Toolkit pour Windows Phone est un projet open source où l'équipe Microsoft Silverlight partage de nouveaux composants et fonctionnalités qui ne sont pas dans le noyau de silverlight pour Windows Phone.
Le Toolkit ajoute donc des contrôles indispensables.
Se rendre sur le site codeplex :
Charger Silverlight for Windows Phone Toolkit pour Mango 7.1.
Ajouter la référence (la DLL) du ToolKit au projet. Dans l'explorateur de solution à droite, clic droit sur référence puis dans le menu clic sur 'Ajouter' une référence.

Puis cliquer sur 'Microsoft.Phone.Controls.ToolKit'.

Dans le code XAML ajouter l'espace de noms 'Microsoft.Phone.Controls.Toolkit' :
|
Maintenant on peut ajouter un contrôle du ToolKit directement dans le code XAML :
|
On peut si on le désire ajouter le contrôle dans la boîte à outils.
Dans celle-ci, click droit sur 'Windows Phone Controls', puis dans le menu 'Choisir les éléments'.

Là on peut cocher le contrôle à ajouter dans la liste de la boîte à outils.
Le ToolKit (version d'octobre 2011) fournit les contrôles suivant :
AutoCompleteBox, ContextMenu, DateTimePicker, DateTimeConverters, ExpanderView, GestureService/GestureListener, HeaderedItemsControl, HubTile, ListPicker, LocalizedResources, LockablePivot, LongListSelector, MultiselectList, Page Transitions, PerformanceProgressBar, PhoneTextBox, TiltEffect, TimePicker, ToggleSwitch, WrapPanel, LockablePivots .
AutoCompleteBox, ContextMenu, DateTimePicker, DateTimeConverters, ExpanderView, GestureService/GestureListener, HeaderedItemsControl, HubTile, ListPicker, LocalizedResources, LockablePivot, LongListSelector, MultiselectList, Page Transitions, PerformanceProgressBar, PhoneTextBox, TiltEffect, TimePicker, ToggleSwitch, WrapPanel, LockablePivots .
AutoCompleteBox permet d'avoir une TextBox proposant une liste de mots dès qu'on tape des lettres.
|
On va charger la liste des mots dans le code-behind :
|

On peut modifier quelques propriétés :
|
On peut ajouter un filtre, afficher des images… voir le libre blanc.
Le DatePicker permet de saisir une date.
|
En C# :
|
On a dans la page ce contrôle :

Quand on clique dessus, la page de saisie de date s'ouvre :

Il faut mettre dans le répertoire "Toolkit.Content" les fichiers "ApplicationBar.Cancel.png" et
"ApplicationBar.Check.png".
Où trouver les fichiers ? Aller sur le site http://silverlight.codeplex.com/releases. Dans 'Other Available Downloads'
charger le zip 'Source Code Silverlight for Windows Phone Toolkit Source and Sample - Nov 2011.zip'. Dans le zip les fichiers png des icônes sont dans 'Source and Samples\PhoneToolkitSample\Toolkit.Content'.
Il faut créer avec l'explorer, un répertoire 'Toolkit.Content' à la racine du projet et y mettre les icônes "ApplicationBar.Cancel.png" et
"ApplicationBar.Check.png" puis ajouter le répertoire au projet (dans l'explorateur de solution, clic sur l'icône 'Afficher tous les fichiers', clic droit sur le répertoire puis 'Ajouter', 'Ajouter le répertoire') ; enfin dans les propriétés de chaque fichier image, 'Action de génération' doit avoir la valeur 'contenu'. Copier doit avoir la valeur 'Copier si plus récent'.

ToggleSwitch est un interrupteur :
|
Ici on le met à 'On' et on ajoute un petit titre au-dessus :

En C# :
|
On peut ajouter les EventHandler 'Checked' et 'Unchecked' et les fonctions correspondantes qui modifient le texte et la couleur du contrôle en fonction de son état 'on' 'off' :
|
On peut simplement tester l'état du ToggleSwitch :
|
Dans le Toolkit il y a aussi le WrapPanel qui est un conteneur où les éléments sont mis à la suite l'un de l'autre mais où il y a "retour à la ligne" quand on atteint la limite du conteneur.
Les éléments se positionnent de gauche à droite et de haut en bas.
Les éléments se positionnent de gauche à droite et de haut en bas.
C'est pratique pour afficher une série de photos comme dans la Media Library de WP.
Exemple du blog d'Audrey Petit, il faut rajouter les binding.
Le template par défaut d'une ListBox n'est autre qu'un StackPanel avec une orientation verticale.
C'est pour cela que les items d'une ListBox se positionnent par défaut les uns en dessous des autres. Nous allons donc modifier ce template afin de lui faire utiliser un WrapPanel et positionner nos éléments les uns à côté des autres, avec passage à la ligne lorsqu'une ligne est complète.
Exemple du blog d'Audrey Petit, il faut rajouter les binding.
Le template par défaut d'une ListBox n'est autre qu'un StackPanel avec une orientation verticale.
C'est pour cela que les items d'une ListBox se positionnent par défaut les uns en dessous des autres. Nous allons donc modifier ce template afin de lui faire utiliser un WrapPanel et positionner nos éléments les uns à côté des autres, avec passage à la ligne lorsqu'une ligne est complète.
|
La Toolbox permet aussi d'ajouter des effets comme le 'Tilt' effect, effet d'appui sur un élément tapé. Cela rend visible les contrôles tapés par le doigt.
|
Le Toolkit ajoute aussi une gestion des gesrures (voir chapitre sur la saisie tactile et les gestures).
Consulter la 'bible' (en anglais) du ToolKit, il y a tout en détail :http://www.windowsphonegeek.com/upload/ebooks/Windows%20Phone%20Toolkit%20Aug%202011%20in%20depth-v1.pdf.
Consulter la 'bible' (en anglais) du ToolKit, il y a tout en détail :http://www.windowsphonegeek.com/upload/ebooks/Windows%20Phone%20Toolkit%20Aug%202011%20in%20depth-v1.pdf.
VI-P. MessageBox
Comment afficher un message pour l'utilisateur sans sortir de la page ?
En utilisant la méthode Show de MessageBox.
En utilisant la méthode Show de MessageBox.
|
Cela donne :

Il y a un bouton 'Ok' par défaut pour sortir du MessageBox.
Sinon on peut ajouter un titre et un bouton annuler.
|

MessageBox peut retourner dans une variable de type MessageBoxResult :
MessageBoxResult.Ok ou MessageBoxResult.Cancel, suivant le bouton qui a été tapé par l'utilisateur.
|
En WP7 il n'y a que deux boutons possible.
VII. Grandes fonctions WP
VII-A. Données

VII-A-1. État de l'application
On peut enregistrer temporairement des données simples (de type clé/valeur) dans le dictionnaire d'état qui est temporaire (elles sont conservées en désactivation et en tombstoned, on perd les infos si le logiciel s'arrête).
Le dictionnaire d'état est accessible par la classe PhoneApplicationService et permet de conserver l'état de l'application (données, Web Service…).
Voir le chapitre sur le tombstone.
Le dictionnaire d'état est accessible par la classe PhoneApplicationService et permet de conserver l'état de l'application (données, Web Service…).
Voir le chapitre sur le tombstone.
Il faut au préalable inclure l'espace de noms Microsoft.Phone.Shell.
|
C'est aussi bien pratique, comme on l'a vu, pour passer des données simples d'une page à l'autre.
On enregistre (avec la clé 'ToDo') :
On enregistre (avec la clé 'ToDo') :
|
Pour récupérer les informations, on peut le faire dans le constructeur de l'autre page par exemple :
|
Autre exemple : pour conserver l'état d'une page, on peut aussi l'enregistrer dans le dictionnaire d'état.
Là on va enregistrer dans la surcharge de la méthode OnNavigatedFrom et lire dans la surcharge de la méthode OnNavigatedTo.
En haut de la classe MainPage, on instancie MyappService de type PhoneApplicationService.
Pour lire, on utilise la méthode TryGetValue qui permet d'éviter les problèmes si la clé n'existe pas.
Là on va enregistrer dans la surcharge de la méthode OnNavigatedFrom et lire dans la surcharge de la méthode OnNavigatedTo.
En haut de la classe MainPage, on instancie MyappService de type PhoneApplicationService.
Pour lire, on utilise la méthode TryGetValue qui permet d'éviter les problèmes si la clé n'existe pas.
|
VII-A-2. Isolated Storage
Pour enregistrer des données, il est préférable d'utiliser l'Isolated Storage.
L'enregistrement est permanent.
'Isoladed' car seule votre application aura accès aux données, pas les autres applications.
Votre application ne pourra pas lire les données d'autres applications.
On peut utiliser 200 Mo par application.
Il y a deux manières d'utiliser l'Isolated Storage :
- l'IsolatedStorageSetting pour enregistrer des clé/valeurs ;
- l'IsolatedStorageFile pour enregistrer des répertoires et des fichiers.
L'enregistrement est permanent.
'Isoladed' car seule votre application aura accès aux données, pas les autres applications.
Votre application ne pourra pas lire les données d'autres applications.
On peut utiliser 200 Mo par application.
Il y a deux manières d'utiliser l'Isolated Storage :
- l'IsolatedStorageSetting pour enregistrer des clé/valeurs ;
- l'IsolatedStorageFile pour enregistrer des répertoires et des fichiers.
Il faut au préalable inclure l'espace de noms :
|
L'IsolatedStorageSetting pour enregistre des clé/valeurs.
Exemple : enregistrer un nom dans le Setting sous la clé 'name'.
Il faut instancier un objet de type IsolatedStorageSettings.ApplicationSettings. La méthode Add permet ensuite d'ajouter une clé/valeur. On peut ensuite lire la valeur correspondant à la clé.
Il faut instancier un objet de type IsolatedStorageSettings.ApplicationSettings. La méthode Add permet ensuite d'ajouter une clé/valeur. On peut ensuite lire la valeur correspondant à la clé.
|
On peut voir si une clé existe :
|
On peut ensuite modifier la valeur d'une clé :
|
On peut effacer une clé :
|
On peut effacer toutes les clés ou compter le nombre de clés.
|
Exemple complet
On enregistre :
On enregistre :
|
Les données qui sont dans le Setting sont enregistrées automatiquement quand l'application (ou la page) qui utilise la classe se termine. On peut forcer l'enregistrement immédiat avec la méthode Save (voir dernière ligne de code qui précède).
On peut aussi enregistrer des objets. Attention, les objets doivent être 'serializables'.
La sérialisation consiste à transformer l'état d'une information qui est en mémoire sous la forme d'une suite d'informations qui pourra être enregistrée ou transportée.
Si on écrit soi-même la classe, il faut la rendre serializable : mettre [DataContract] avant la classe et [DataMember] avant les champs publics.
Il faut ajouter :
|
|
Exemple :
soit une classe 'ElementDeListe' permettant d'instancier un objet currentCalcul.
On va enregistrer currentCalcul (dans OnNavigatedFrom par exemple) :
soit une classe 'ElementDeListe' permettant d'instancier un objet currentCalcul.
On va enregistrer currentCalcul (dans OnNavigatedFrom par exemple) :
|
On va lire currentCalcul (dans OnNavigatedTo par exemple) :
|
L'IsolatedStorageFile pour enregistrer des fichiers.
Pour pouvoir utiliser l'Isolated Storage il faut récupérer une
référence vers le conteneur dédié à votre application. Cela se fait avec la méthode statique
GetUserStoreForApplication de la classe IsolatedStorageFile.
À partir d'une instance de la classe IsolatedStorageFile, il est possible de manipuler répertoires et fichiers grâce aux méthodes.
À partir d'une instance de la classe IsolatedStorageFile, il est possible de manipuler répertoires et fichiers grâce aux méthodes.
FileExists.
CreateFile.
OpenFile.
DeleteFile.
DirectoryExists.
CreateDirectory.
DeleteDirectory.
Remove.
On peut écrire et lire des fichiers avec des IsolatedStorageFileStream.
Un 'Stream' est un flux de données.
Vous pouvez lire à partir des flux. La lecture est le transfert de données d'un flux vers une structure de données (du texte avec ReadLine, par exemple).
Vous pouvez écrire dans les flux. L'écriture est le transfert de données d'une structure de données vers un flux (du texte avec ReadLine, par exemple).
CreateFile.
OpenFile.
DeleteFile.
DirectoryExists.
CreateDirectory.
DeleteDirectory.
Remove.
On peut écrire et lire des fichiers avec des IsolatedStorageFileStream.
Un 'Stream' est un flux de données.
Vous pouvez lire à partir des flux. La lecture est le transfert de données d'un flux vers une structure de données (du texte avec ReadLine, par exemple).
Vous pouvez écrire dans les flux. L'écriture est le transfert de données d'une structure de données vers un flux (du texte avec ReadLine, par exemple).
|
VII-A-3. LINQ To SQL, données sur le Web
Il est possible d'utiliser une base de données locale et de l'interroger avec LINQ to SQL.
Il y a plusieurs réseaux et technologies Web service que vous pouvez utiliser pour récupérer des données distantes :
HTTP classes ;
WCF services ;
WCF Data Services (OData services) ;
Windows Azure Services.
HTTP classes ;
WCF services ;
WCF Data Services (OData services) ;
Windows Azure Services.
VII-B. Activation, désactivation, Tombstone.

Terminer une application
On se souvient que, sur la page principale (la première page) d'une application, si on fait 'Retour' (Back bouton de gauche), on sort de l'application elle est fermée.
Si on veut utiliser de nouveau l'application, il faut la relancer.
On se souvient que, sur la page principale (la première page) d'une application, si on fait 'Retour' (Back bouton de gauche), on sort de l'application elle est fermée.
Si on veut utiliser de nouveau l'application, il faut la relancer.
Suspendre une application
Si par, contre, il y a un appel téléphonique ou si on fait 'Démarrer' (bouton du milieu avec logo Windows), l'application est désactivée.
L'utilisateur est censé y revenir et poursuivre l'utilisation de l'application.
Avec le bouton 'Back', on peut revenir dans l'application et poursuivre.
(Si on clique sur l'icône du programme, l'application est relancée et redémarre à zéro.)
Si par, contre, il y a un appel téléphonique ou si on fait 'Démarrer' (bouton du milieu avec logo Windows), l'application est désactivée.
L'utilisateur est censé y revenir et poursuivre l'utilisation de l'application.
Avec le bouton 'Back', on peut revenir dans l'application et poursuivre.
(Si on clique sur l'icône du programme, l'application est relancée et redémarre à zéro.)
Durant la désactivation, pendant un 'certain temps' WP conserve toutes les données (c'est l'état dormant) ; si on utilise 'Back', on va réactiver l'application et se retrouver dans la même page avec les données affichées dans les TextBox par exemple.
État Tombstone
Il n'est pas possible que toutes les applications désactivées restent au stade 'désactivé' (dormant) éternellement.
Donc après un 'certain temps', et sans prévenir, quand WP a besoin de place, il fait une désactivation totale dite 'Tombstone' (pierre tombale) ; l'OS tue le process ; et là, si ensuite on fait 'Back', on se retrouve dans la page qu'on avait quittée mais on a perdu les informations contenues dans la page (et les données de l'application) qui est réactivée.
Il n'est pas possible que toutes les applications désactivées restent au stade 'désactivé' (dormant) éternellement.
Donc après un 'certain temps', et sans prévenir, quand WP a besoin de place, il fait une désactivation totale dite 'Tombstone' (pierre tombale) ; l'OS tue le process ; et là, si ensuite on fait 'Back', on se retrouve dans la page qu'on avait quittée mais on a perdu les informations contenues dans la page (et les données de l'application) qui est réactivée.
En effet, Windows Phone enregistre la pile de retour d'une application lors d'une désactivation Tombstone. Au moment de l'activation, il restaure uniquement la dernière page qui était active avant la désactivation Tombstone de l'application (mais pas les données, les objets ni les contenus des contrôles, des TextBox…).
L'état persistant de l'application (le contenu des contrôles visuels, les données, les objets) doit être enregistré par l'application avant la désactivation. C'est au programmeur de le faire.
L'état persistant de l'application (le contenu des contrôles visuels, les données, les objets) doit être enregistré par l'application avant la désactivation. C'est au programmeur de le faire.
Voici le cycle de vie d'une application WP donné par Microsoft :

![]() | Si on veut réactiver une application qui est tombstoned et poursuivre là où on était, l'OS se chargera de réafficher la dernière page mais il appartient au programmeur d'enregistrer l'état de la page (Page State= contenu des contrôles de la page) et les données de l'application (Application State) lors de la désactivation et de les restituer à la réactivation. |
Voyons les évènements que propose WP pour faire cela.
A - Activated, Desactivated de l'application
Dans App.xaml.cs
Les évènement Launching (lancement) et Closing (fermeture) sont exécutés au lancement et à la fermeture de l'application. C'est classique.
Les évènement Activated (activé) et Desactivated (désactivé) sont moins habituels, ils sont exécutés quand on retourne à l'application et, au cours de l'exécution de votre application, quand on utilise le bouton 'démarrer' (bouton du milieu) ou quand le téléphone sonne.
Dans App.xaml.cs
Les évènement Launching (lancement) et Closing (fermeture) sont exécutés au lancement et à la fermeture de l'application. C'est classique.
Les évènement Activated (activé) et Desactivated (désactivé) sont moins habituels, ils sont exécutés quand on retourne à l'application et, au cours de l'exécution de votre application, quand on utilise le bouton 'démarrer' (bouton du milieu) ou quand le téléphone sonne.
|
Si l'application est lancée (launching) Application_Activated n'est pas exécuté. L'inverse est vrai.
Idem pour Deactivated et Closing.
Idem pour Deactivated et Closing.
![]() | Utilisez les événements Deactivated et Activated de l'application pour les données et objets de l'application. |
On utilise dans ce cas l'application Setting.
Bien se souvenir que le stockage dans l'application Setting est temporaire et ne dure que le temps pendant lequel l'application est tombstoned. Quand l'application est totalement arrêtée, on perd l'application Setting. Si on veut un enregistrement persistant il faut utiliser l'IsolatedStorage.
Bien se souvenir que le stockage dans l'application Setting est temporaire et ne dure que le temps pendant lequel l'application est tombstoned. Quand l'application est totalement arrêtée, on perd l'application Setting. Si on veut un enregistrement persistant il faut utiliser l'IsolatedStorage.
Exemple simple utilisant l'ApplicationSettings :
|
Pour la réactivation on peut utiliser 'private void Application_activated'.
|
B - OnNavigatedFrom, OnNavigatedFrom de la page
On a dans la page les évènement OnNavigatedFrom et OnNavigatedTo que l'on peut surcharger.
OnNavigatedTo est exécuté lors de toutes les navigations vers la page (lorsque l'utilisateur arrive sur la page).
OnNavigatedFrom est exécuté lors de toutes les navigations sortant de la page (lorsque l'utilisateur quitte la page).
Le constructeur de page est appelé, lui, lors de la première navigation sur cette page (appelé une seule fois).
On a dans la page les évènement OnNavigatedFrom et OnNavigatedTo que l'on peut surcharger.
OnNavigatedTo est exécuté lors de toutes les navigations vers la page (lorsque l'utilisateur arrive sur la page).
OnNavigatedFrom est exécuté lors de toutes les navigations sortant de la page (lorsque l'utilisateur quitte la page).
Le constructeur de page est appelé, lui, lors de la première navigation sur cette page (appelé une seule fois).

|
![]() | On utilise OnNavigatedFrom et OnNavigatedTo pour l'état de page (contenu des contrôles). |
Je l'utilise aussi pour les objets propres à la page.
Exemple :
|
Comment savoir si l'application désactivée a un état Tombstone ?
Avec la méthode IsApplicationInstancePreserved :
Avec la méthode IsApplicationInstancePreserved :
|
Dans le cas où on utilise un pattern MVVM, on peut sauvegarder et restaurer l'objet ViewModel lui-même.
|
Le site CodePlex fourni en open Source TombstoneHelper.dll qui permet de sauvegarder et restaurer automatiquement l'état de la page, le contenu des contrôles d'une page .
Voir : tombstonehelper
Il faut charger tombstonehelper.dll dans le projet. Comme elle vient d'Internet et que Windows interdit d'utiliser une DLL non sure, Visual Studio refuse de l'utiliser, il faut donc cliquer droit sur la DLL dans l'explorateur, choisir 'propriétés' ; en bas il y a un bouton qui débloque la DLL à vos risques et périls (attention, il y a des copies de la DLL dans les répertoires bin et release du projet, il faut les débloquer aussi si on ne la pas fait au départ).
Ensuite il faut ajouter la référence au projet : clic droit sur 'références' dans l'explorateur de solution puis 'Ajouter une référence' ; ajouter tombstonehelper.dll.
Enfin il faut ajouter l'espace de noms nécessaire :
|
Pour sauver et restaurer la totalité des contrôles (TextBox, PasswordBoxe, CheckBoxe, RadioButton, Slider, ListBoxe et ScrollViewer, PAS les TextBlock !) c'est simple :
|
Pour un type de contrôle :
|
Attention, les contrôles doivent avoir un nom (attribut 'Name').
On se souvient que les TextBlock ne sont pas sauvés (pour certains résultats j'ai préféré utiliser des TextBox avec l'attribut IsReadOnly à true plutôt que des TextBlock).
On se souvient que les TextBlock ne sont pas sauvés (pour certains résultats j'ai préféré utiliser des TextBox avec l'attribut IsReadOnly à true plutôt que des TextBlock).
Microsoft.Phone.Shell.PhoneApplicationService.Current.ApplicationIdleDetectionMode = Microsoft.Phone.Shell.IdleDetectionMode.Disabled :
permet à votre application de ne pas se faire tombstonner quand le téléphone se met en veille, en clair votre application tourne derrière le lockscreen. C'est le comportement le plus proche d'un thread d'arrière-plan.
Microsoft.Phone.Shell.PhoneApplicationService.Current.UserIdleDetectionMode = Microsoft.Phone.Shell.IdleDetectionMode.Disabled :
permet de désactiver purement et simplement le lockscreen !
permet à votre application de ne pas se faire tombstonner quand le téléphone se met en veille, en clair votre application tourne derrière le lockscreen. C'est le comportement le plus proche d'un thread d'arrière-plan.
Microsoft.Phone.Shell.PhoneApplicationService.Current.UserIdleDetectionMode = Microsoft.Phone.Shell.IdleDetectionMode.Disabled :
permet de désactiver purement et simplement le lockscreen !
Pour tester dans l'émulateur l'effet Tombstone il faut passer par le menu 'projet' puis 'propriété de', onglet 'déboguer'.

Si on ne coche pas, il y a désactivation sans Tombstone.
VII-C. Le pattern Model-View-ViewModel
Un pattern est un modèle de structure d'une application.
Le pattern M-V-VM (Model-View-ViewModel) permet une séparation entre
la couche dédiée aux objets métiers (Model),
à l'interface graphique (View),
à la logique (ViewModel).
la couche dédiée aux objets métiers (Model),
à l'interface graphique (View),
à la logique (ViewModel).
C'est ce pattern qu'il est conseillé d'utiliser sur WP.
Il y a de très bon article sur le Web :
Je dois vous avouer que, pour moi, cela semble très obscur, complexe et difficile à gérer. Mais cela n'engage que moi !
VII-D. Orientation
Le WP peut fonctionner :
en 'Portrait' ou en 'LandScape' (paysage).
en 'Portrait' ou en 'LandScape' (paysage).

Dans le code XAML de la page, on a les orientations supportées ('Portrait', 'LandScape', 'PortraitOrLandscape').
Il y a aussi l'orientation initiale('Portrait', 'LandScape').
Il y a aussi l'orientation initiale('Portrait', 'LandScape').
|
Il est possible de détecter un changement d'orientation en
surchargeant la méthode OnOrientationChanged et en regardant l'OrientationChangedEventArgs.
|
e.Orientation a une des valeurs de l'énumération PageOrientation (Bit Flags) :
- PageOrientation.PortraitUp ;
- PageOrientation.PortraitDown ;
- PageOrientation.LandscapeLeft ;
- PageOrientation.LandscapeRight.
- PageOrientation.PortraitUp ;
- PageOrientation.PortraitDown ;
- PageOrientation.LandscapeLeft ;
- PageOrientation.LandscapeRight.
L'énumération comporte aussi les valeurs PageOrientation.Portrait et PageOrientation.Landscape.
En utilisant un 'ou' entre e.Orientation et PageOrientation.Landscape on determine si on est en LandscapeLeft ou LandscapeRight.
En utilisant un 'ou' entre e.Orientation et PageOrientation.Landscape on determine si on est en LandscapeLeft ou LandscapeRight.
|
C'est l'équivalent de :
|
C'est l'endroit parfait pour modifier les dimensions et positions des contrôles en fonction de l'orientation.
|
Le plus simple pour positionner les contrôles dans les deux orientations est de les mettre dans un StackPanel qui lui-même sera dans un ScrollViewer. Comme cela, en mode paysage, les contrôles peuvent 'déborder' en bas.
VII-E. Lanceur d'applications internes
Impossible de lancer, à partir de votre application, une de vos autres applications ou même une application présente sur votre WP comme Internet Explorer (sécurité oblige).
Seules exceptions :
Les Launchers (lanceurs) et Choosers (sélecteurs) permettent d'accéder aux Windows Phone applications. Par exemple, si vous voulez chercher un contact à partir de votre application, il faut utiliser EmailAddressChooserTask.
On peut ainsi, à partir de votre application, envoyer un mail ou un coup de téléphone, prendre une photo, ouvrir une page Web.
La différence entre Launchers et Choosers est que les Launchers ne retournent pas de données contrairement aux Choosers. L' EmailComposeTask Launcher par exemple démarre l'email application qui se fermera simplement. La CameraCaptureTask Chooser démarre l'application 'camera', à sa sortie cette application fournit la photo qui à été prise.
On peut ainsi, à partir de votre application, envoyer un mail ou un coup de téléphone, prendre une photo, ouvrir une page Web.
La différence entre Launchers et Choosers est que les Launchers ne retournent pas de données contrairement aux Choosers. L' EmailComposeTask Launcher par exemple démarre l'email application qui se fermera simplement. La CameraCaptureTask Chooser démarre l'application 'camera', à sa sortie cette application fournit la photo qui à été prise.
Il faut ajouter :
|
Launchers (lanceur).
Voici les lanceurs :
EmailComposeTask permet d'envoyer un mail ;
MarketplaceDetailTask permet de lancer le 'Windows Phone Marketplace client application' et affiche le détail d'un produit du Market Place ;
MarketplaceHubTask Permet de lancer le 'Windows Phone Marketplace client application' ;
MarketplaceSearchTask permet de lancer le 'Windows Phone Marketplace client application' et de voir le résultat d'une recherche sur un thème ;
MediaPlayerLauncher permet de lancer le 'media player' ;
PhoneCallTask permet de lancer la 'Phone application' et de faire un appel téléphonique ;
SearchTask permet de lancer le 'web search application' pour rechercher sur le Web ;
SmsComposeTask permet de lancer le 'Messaging application' et de faire un nouveau message SMS ;
WebBrowserTask permet de lancer le browser Internet.
MarketplaceDetailTask permet de lancer le 'Windows Phone Marketplace client application' et affiche le détail d'un produit du Market Place ;
MarketplaceHubTask Permet de lancer le 'Windows Phone Marketplace client application' ;
MarketplaceSearchTask permet de lancer le 'Windows Phone Marketplace client application' et de voir le résultat d'une recherche sur un thème ;
MediaPlayerLauncher permet de lancer le 'media player' ;
PhoneCallTask permet de lancer la 'Phone application' et de faire un appel téléphonique ;
SearchTask permet de lancer le 'web search application' pour rechercher sur le Web ;
SmsComposeTask permet de lancer le 'Messaging application' et de faire un nouveau message SMS ;
WebBrowserTask permet de lancer le browser Internet.
Il faut instancier le lanceur, renseigner certaines propriétés puis appliquer la méthode Show.
Exemple 1 : appeler un numéro à partir de votre application.
|
On a l'écran :

Puis la page habituelle du téléphone.
Exemple 2 : faire une recherche sur le Web.
|
On a l'écran :

On a ensuite les réponses à la recherche "cours Windows Phone" sur le Web :

Choosers (sélecteurs).
Voici les Choosers
CameraCaptureTask lance la 'Camera application'. Permet de récupérer la photo prise ;
EmailAddressChooserTask lance la 'Contacts application'. On récupère l'adresse du contact sélectionné par l'utilisateur ;
PhoneNumberChooserTask lance la 'Contacts application'. On récupère le numéro de téléphone du contact sélectionné par l'utilisateur ;
PhotoChooserTask lance la 'Photo Chooser application'. Retourne la photo sélectionnée ;
SaveEmailAddressTask permet de sauvegarder une adresse mail ;
SavePhoneNumberTask permet de sauvegarder un numéro de téléphone ;
GameInviteTask permet d'accepter un joueur dans un jeu multi joueur ;
SaveRingtoneTask utilise le 'save ringtone task' pour permettre à l'utilisateur de sauvegarder un fichier audio file dans le 'system ringtones' list (les sonneries).
EmailAddressChooserTask lance la 'Contacts application'. On récupère l'adresse du contact sélectionné par l'utilisateur ;
PhoneNumberChooserTask lance la 'Contacts application'. On récupère le numéro de téléphone du contact sélectionné par l'utilisateur ;
PhotoChooserTask lance la 'Photo Chooser application'. Retourne la photo sélectionnée ;
SaveEmailAddressTask permet de sauvegarder une adresse mail ;
SavePhoneNumberTask permet de sauvegarder un numéro de téléphone ;
GameInviteTask permet d'accepter un joueur dans un jeu multi joueur ;
SaveRingtoneTask utilise le 'save ringtone task' pour permettre à l'utilisateur de sauvegarder un fichier audio file dans le 'system ringtones' list (les sonneries).
Il faut instancier le Chooser, instancier un EventHandle sur l'évènement Completed du Chooser, renseigner certaines propriétés puis appliquer la méthode Show.
Il faut récupérer la valeur retournée par le Chooser dans la fonction évènement déclenchée par Completed (Completed survient quand l'application Chooser est terminée).
Il faut récupérer la valeur retournée par le Chooser dans la fonction évènement déclenchée par Completed (Completed survient quand l'application Chooser est terminée).
Exemple 1 : récupérer un numéro de téléphone dans les contacts.
|
Exemple 2 : à partir de mon application, prendre une photo puis dans mon application, l'afficher.
|
Maintenant, on a la fonction évènement qui survient quand la tache 'photo' est terminée.
|
Exemple 3 : à partir de mon application, enregistrer un contact dans les contacts.
|
Maintenant, on a la fonction évènement qui survient quand la tache est terminée.
|
Dans le chapitre 'Utiliser un WebBrowser' il y a un exemple d'utilisation du WebBrowseTask pour visionner des pages du Web.
VII-F. Les thèmes
Dans les paramètres du Windows Phone on peut choisir :
l'arrière plan light ou dark (clair ou sombre),
la couleur d'accentuation (11 couleurs proposées).
l'arrière plan light ou dark (clair ou sombre),
la couleur d'accentuation (11 couleurs proposées).

Voici les 10 couleurs version 7.1 (en 7.0 magenta et lime sont légèrement différents), en plus il y a une onzième couleur réservée à l'opérateur ou au fabriquant (sur le mien c'est 'Orange F').

Ces couleurs se retrouvent dans les ressources Windows Phones :
la couleur de fond est : PhoneBackgroundColor.
La couleur d'accentuation est : PhoneAccentColor.
Pour le texte : PhoneForegroundColor.
Dans le code XAML quand on utilise des ressources comme couleur, ce sont les 'Brush' qu'il faut utiliser et pas les couleurs.
PhoneAccentBrush :Brush d'accentuation définie par le thème.
PhoneForegroundBrush :Brush utilisée pour les éléments de premier plan tels que le texte ou les icônes.
PhoneBackgroundBrush :Brush utilisée pour les éléments d'arrière-plan.
PhoneContrastBackgroundBrush :Brush de fond utilisée pour mettre en contraste (fond des menus contextuels par exemple).
PhoneContrastForegroundBrush :Brush de premier plan utilisée pour les éléments à mettre en contraste. Par exemple les textes des menus contextuels.
PhoneDisabledBrush :Brush des éléments désactivés.
PhoneSubtleBrush :Brush partiellement transparente qui permet de mettre en retrait des éléments visuels moins importants.
PhoneBorderBrush :Brush de bordure des contrôles TextBox, CheckBox, PasswordBox, et RadioButton.
PhoneSemitransparentBrush :Brush presque transparente permettant de faire ressortir des éléments de couleurs similaires (par exemple du texte blanc sur une image claire).
La couleur d'accentuation est : PhoneAccentColor.
Pour le texte : PhoneForegroundColor.
Dans le code XAML quand on utilise des ressources comme couleur, ce sont les 'Brush' qu'il faut utiliser et pas les couleurs.
PhoneAccentBrush :Brush d'accentuation définie par le thème.
PhoneForegroundBrush :Brush utilisée pour les éléments de premier plan tels que le texte ou les icônes.
PhoneBackgroundBrush :Brush utilisée pour les éléments d'arrière-plan.
PhoneContrastBackgroundBrush :Brush de fond utilisée pour mettre en contraste (fond des menus contextuels par exemple).
PhoneContrastForegroundBrush :Brush de premier plan utilisée pour les éléments à mettre en contraste. Par exemple les textes des menus contextuels.
PhoneDisabledBrush :Brush des éléments désactivés.
PhoneSubtleBrush :Brush partiellement transparente qui permet de mettre en retrait des éléments visuels moins importants.
PhoneBorderBrush :Brush de bordure des contrôles TextBox, CheckBox, PasswordBox, et RadioButton.
PhoneSemitransparentBrush :Brush presque transparente permettant de faire ressortir des éléments de couleurs similaires (par exemple du texte blanc sur une image claire).
Exemple :
|
On peut aussi utiliser les styles :
PhoneTextNormalStyle qui utilise judicieusement une couleur (PhoneForegroundBrush) qui contraste bien avec la PhoneBackgroundColor du thème. Si le background est dark, PhoneTextNormalStyle donnera du texte blanc (FontSize : 20).
Il y a aussi PhoneTextTitle1Style (FontSize : 72, PhoneForegroundBrush), PhoneTextTitle2Style (FontSize : 32, PhoneForegroundBrush)…
|
On se rend compte qu'à partir de la couleur d'accentuation et du fond, les styles s'adaptent pour être lisibles et cohérents.
Sélecteur de ressource : dans la fenêtre 'Propriétés', pour donner une valeur ressource à la propriété d'un contrôle (BackGround par exemple), on peut ouvrir le sélecteur de ressource en cliquant sur le carré à côté du nom de la propriété :

Dans le menu, choisir 'Appliquer la ressource'.

Double-cliquer sur la ressource désirée.
Comment utiliser les couleurs du thème choisi par l'utilisateur ?
On va créer une page avec un fond dégradé à partir des deux couleurs PhoneBackgroundColor et PhoneAccentColor.
Le titre de la page utilisera le style PhoneAccentColor. Le texte affiché aura le Style PhoneTextNormalStyle.
|
Voici le résultat : avec un fond foncé et une couleur d'accentuation marron puis avec un fond clair et une couleur d'accentuation bleue.

![]() | Le résultat est parfait, le texte toujours lisible quelque soit le choix du fond et de la couleur d'accentuation. |
![]() |
Si on n'indique rien comme style ou couleur, par défaut le thème courant est utilisé : texte blanc si le fond est 'dark' et texte noir si le fond est 'light' plus couleur d'accentuation. Si on indique des couleurs, pour le fond par exemple, il faut bien veiller à ce que la couleur du texte soit lisible et tester son application avec les différents fonds et couleurs d'accentuation. |
Comment savoir si on a un Background Dark ou Light ?
|
Comment connaître la couleur d'accentuation ?
|
VII-G. Vibreur
Il faut inclure l'espace de noms Microsoft.Devices et instancier un VibrateControler avec la méthode static Default.
|
Il y a une exception si l'argument de Start est négatif ou supérieur à cinq secondes.
On a aussi la méthode Stop.
Combien de temps faire vibrer ?
100 ms pour signaler la pression d'une touche.
300 ms pour attirer l'attention de l'utilisateur.
2 s : non !
VII-H. Localisation
Le Windows Phone utilise trois moyens pour se localiser :
- avec les relais émetteurs cellulaires ;
- avec la Wi-Fi ;
- avec les satellites GPS.
Avec les relais c'est rapide mais peu précis. Avec le GPS c'est précis mais lent et cela ne marche pas à l'intérieur. Avec la WiFi, il faut être en ville.
Les informations des relais et de la Wi-Fi arrivent en quelques secondes ; pour le GPS c'est quelques minutes.
Le WP utilise les trois (il faut, dans les paramètres du WP, que la localisation soit activée).
Les informations des relais et de la Wi-Fi arrivent en quelques secondes ; pour le GPS c'est quelques minutes.
Le WP utilise les trois (il faut, dans les paramètres du WP, que la localisation soit activée).
Comment trouver sa localisation (latitude, longitude, vitesse, orientation, altitude) ?
Il faut charger la référence (la DLL) 'System.Device' (clic droit sur 'Références' dans l'explorateur de projet puis 'Ajouter une référence').
Puis ajouter l'espace de noms System.Device.Localisation.
Il faut instancier un GeoCoordinateWatcher, créer un EventHandler sur l'évènement PositionChanged.
À chaque fois que la position du WP change, l'évènement PositionChanged est exécuté et donc la fonction 'gcw_PositionChanged'.
Il faut démarrer la localisation avec la méthode Start.
On affiche ensuite la latitude, la longitude, la vitesse, la direction en degrés par rapport au nord géographique, l'altitude (dans cinq TextBlock).
Il faut instancier un GeoCoordinateWatcher, créer un EventHandler sur l'évènement PositionChanged.
À chaque fois que la position du WP change, l'évènement PositionChanged est exécuté et donc la fonction 'gcw_PositionChanged'.
Il faut démarrer la localisation avec la méthode Start.
On affiche ensuite la latitude, la longitude, la vitesse, la direction en degrés par rapport au nord géographique, l'altitude (dans cinq TextBlock).
|
Pour tester l'application dans l'émulateur, il faut ouvrir la fenêtre suivante grâce au bouton'>>" situé à droite de l'émulateur, puis cliquer sur l'onglet 'Localisation' :

Dans la zone de recherche, en haut à gauche, il faut saisir un lieu, cela affiche une carte. Le fait de cliquer sur la carte affiche en bas les coordonnées du lieu.
Ces coordonnées seront utilisées dans l'émulateur (pas de vitesse, direction et altitude).
Ces coordonnées seront utilisées dans l'émulateur (pas de vitesse, direction et altitude).
Afin d'éviter les plantages, on peut gérer le Status du GeoCoorditaneWatcher afin de savoir si la localisation est activée, si le WP reçoit des données :
Il faut créer un évènement :
|
On peut ajouter un paramètre lors de l'initialisation pour forcer à plus de précision :
|
La valeur par défaut est 'Default'.
La précision High peut nuire aux performances.
La précision High peut nuire aux performances.
On peut aussi indiquer la distance de déplacement pour déclencher PositionChanged :
|
VII-I. Accéléromètre
Windows Phone contient un espace de noms dédié à la gestion et l'exploitation en temps réel des données de l'accéléromètre du téléphone. L'accéléromètre mesure l'intensité et la direction de la force d'accélération appliquée sur le téléphone. La valeur de cette force suivant les axes X, Y, Z, se retrouve dans une variable décimale (valeurs de -1.0 à 1.0), l'unité étant le 'g' (1g = attraction de la force terrestre).
Voici le sens des vecteurs X, Y, Z :

L'attraction terrestre ayant la valeur 1, voici les valeurs x y z pour les divers positions du phone.

Dans le code il faut inclure l'espace de noms nécessaire :
|
Il faut ensuite instancier l'accéléromètre et ajouter un EventHandler sur l'évènement :
|
|
|
Pour tester l'application dans l'émulateur, il faut ouvrir la fenêtre suivante grâce au bouton'>>" situé à droite de l'émulateur puis cliquer sur l'onglet 'accéléromètre' :

En déroulant la liste 'Orientation' en bas à gauche, on peut choisir différentes valeurs de X, Y, Z.
VII-J. Internet, WebBrowser, WebClient
Le Windows Phone est-il connecté à internet ?
|
NetworkInterfaceType retourne :
None si pas de connexion ;
Wireless80211 si connexion Wi-Fi ;
Ethernet ;
MobileBroadbandGSM ou MobileBroadbandCDMA si réseau téléphone mobile.
None si pas de connexion ;
Wireless80211 si connexion Wi-Fi ;
Ethernet ;
MobileBroadbandGSM ou MobileBroadbandCDMA si réseau téléphone mobile.
Comment charger dans un Browser une page qui est sur le Web ?
On peut utiliser un lanceur de tache pour utiliser l'application 'WebBrowser'.
Il faut ajouter un espace de noms :
|
Ensuite il faut utiliser un WebBrowserTask :
|

On peut mettre un contrôle 'WebBrowser' dans la page.
En allant le chercher dans la boîte à outils :
En allant le chercher dans la boîte à outils :
|
En ajoutant la source :
|
ou en instanciant un WebBrowser dans le code C# :
|
Ensuite on peut naviguer vers une page.
|
Pas de GoBack, GoFoward...
Dans ce WebBrowser on peut aussi afficher du HTML grâce à NavigateToString :
|
SaveToString retourne une string contenant le code HTML de la page.
Pour charger un fichier situé sur Internet, on peut utiliser un WebClient.
Un WebClient a des méthodes pour l'envoi de données à une ressource locale, intranet ou Internet identifiée par un URI ou pour la réception de données en provenance de cette ressource.
Ici on va charger une image :
Un WebClient a des méthodes pour l'envoi de données à une ressource locale, intranet ou Internet identifiée par un URI ou pour la réception de données en provenance de cette ressource.
Ici on va charger une image :
|
VII-K. Radio FM
Simple pour mettre en marche la radio FM.
|
puis
|
VII-L. Minuterie
On peut utiliser une minuterie grâce à la classe DispatcherTimer de espace de noms System.Windows.Threading du framework.
Elle déclenche un évènement Tick tous les 'Interval' de temps.
Créons une application qui affiche date, heure, minute, seconde et se met à jour toutes les secondes.
Elle déclenche un évènement Tick tous les 'Interval' de temps.
Créons une application qui affiche date, heure, minute, seconde et se met à jour toutes les secondes.
|
Les opérations DispatcherTimer sont placées dans la file d'attente Dispatcher. Le moment d'exécution de l'opération DispatcherTimer dépend des autres travaux de la file d'attente et de leur priorité ; ainsi l'évènement Tick se produira peut-être pas exactement durant l'intervalle de temps défini, au moins après un intervalle, parfois plus.
Il s'exécute dans le thread interface utilisateur (UI).
Il s'exécute dans le thread interface utilisateur (UI).
Il existe un autre Timer dans l'espace de noms System.Threading :
Il fonctionne dans un thread d'arrière-plan.
Il fonctionne dans un thread d'arrière-plan.
|
Si on avait voulu afficher l'heure dans la méthode TimerCallBack, il y aurait eu levée d'une exception 'Invalid cross-thread access' car le Timer est dans un thread différent du thread de l'interface. Le thread du Timer doit déléguer le travail au Dispatcher associé au thread d'interface utilisateur grâce à BeginInvoke.
System.Threading.Timer n'est pas recommandé pour les scénarios dans lesquels l'interface d'utilisateur doit être actualisée, parce que ses callback ne se produisent pas sur le thread d'interface d'utilisateur. Système.Windows.DispatcherTimer est un meilleur choix dans ces scénarios,
parce que ses événements sont levés sur le thread d'interface d'utilisateur.
VII-M. Applications en tâche de fond : alarme, rappel
La classe 'Alarme' de l'espace de noms 'Microsoft.Phone.Scheduler' permet de créer une alarme.
On va créer une alarme nommée 'MonAlarme' ; elle se déclenchera dans 20 s et affichera "Debout".
On va créer une alarme nommée 'MonAlarme' ; elle se déclenchera dans 20 s et affichera "Debout".
|
RecurrenceInterval peut être Daily, Weekly, Monthly, Yearly, None, EndOfMonth.
ExpirationTime indique à quel moment arrêter le service.
Sound permet d'ajouter l'URI d'un fichier son qui sera exécuté lors de l'alarme. Le fichier son doit être dans le répertoire source et chargé dans l'application comme contenu.
ExpirationTime indique à quel moment arrêter le service.
Sound permet d'ajouter l'URI d'un fichier son qui sera exécuté lors de l'alarme. Le fichier son doit être dans le répertoire source et chargé dans l'application comme contenu.

Si on relance l'application une seconde fois et qu'on veut créer de nouveau une alarme nommée 'MonAlarme', il y a levée d'une exception car elle existe toujours (même si on a quitté l'application).
Il est possible de détruire cette alarme :
Il est possible de détruire cette alarme :
|
On peut aussi utiliser un Reminder ou rappel : chaque 2 juin à 21 h 40 rappeler que c'est l'anniversaire de 'Mimi'.
|

VII-N. Informations diverses
Grâce à DeviceExtendedProperties de l'espace de noms Microsoft.Phone.Info on peut lire des informations sur le téléphone : fabricant, nom, version du Firmware et du Hardware, mémoire totale, mémoire utilisée par l'application, 'ApplicationPeakMemoryUsage', ID du téléphone.
|
|
Il existe aussi DeviceStatus (à partir de WP 7.1) qui permet de voir toutes les informations précédentes avec une syntaxe plus simple.
Mais en plus :
PowerSource qui retourne Battery ou External (secteur) ;
ApplicationMemoryUsageLimit (mémoire que l'application peut utiliser) ;
IsKeyboardPresent IsKeyboardDeployed.
Mais en plus :
PowerSource qui retourne Battery ou External (secteur) ;
ApplicationMemoryUsageLimit (mémoire que l'application peut utiliser) ;
IsKeyboardPresent IsKeyboardDeployed.
|
Le portable supporte-t-il le smooth streaming des multi-resolution encoded video ?
|