Notre première application
Nous avons désormais tous les outils qu’il faut pour commencer à apprendre à réaliser des applications pour Windows Phone.
Nous avons pu voir que ces outils fonctionnent et nous avons pu constater un début de résultat grâce à l’émulateur. Mais pour bien comprendre et assimiler toutes les notions, nous avons besoin de plus de concret, de manipuler des éléments et de voir qu’est-ce qui exactement agit sur quoi. Aussi, il est temps de voir comment réaliser une première application avec le classique « Hello World » !
Cette première application va nous servir de base pour commencer à découvrir ce qu’il faut pour réaliser des applications pour Windows Phone.
Nous avons pu voir que ces outils fonctionnent et nous avons pu constater un début de résultat grâce à l’émulateur. Mais pour bien comprendre et assimiler toutes les notions, nous avons besoin de plus de concret, de manipuler des éléments et de voir qu’est-ce qui exactement agit sur quoi. Aussi, il est temps de voir comment réaliser une première application avec le classique « Hello World » !
Cette première application va nous servir de base pour commencer à découvrir ce qu’il faut pour réaliser des applications pour Windows Phone.
Hello World
Revenons
donc sur notre écran où nous avons le designer et le XAML.
Positionnons-nous sur le code XAML et ajoutons des éléments sans trop
comprendre ce que nous allons faire afin de réaliser notre « Hello World
». Nous reviendrons ensuite sur ce que nous avons fait pour expliquer
le tout en détail.
Pour commencer, on va modifier la ligne suivante :
Text="nom de la page" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"
et écrire ceci :
Text="Hello World" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"
Nous changeons donc la valeur de l’attribut
Text
de la balise <TextBlock>
.
Ensuite, juste après :
x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"
Donc, à l’intérieur de cette balise
<Grid>
, rajoutez :
Text="Saisir votre nom" HorizontalAlignment="Center"
x:Name="Nom"
Content="Valider" Tap="Button_Tap_1"
x:Name="Resultat" Foreground="Red"
Remarquez que lorsque vous avez saisi la ligne :
Content="Valider" Tap="Button_Tap_1"
au moment de taper :
Tap=""
, Visual Studio Express vous a proposé de générer un nouveau gestionnaire d’événement (voir la figure suivante).
Vous pouvez le générer en appuyant sur Entrée, cela nous fera gagner du temps plus tard. Sinon, ce n’est pas grave.
Vous pouvez constater que le designer s’est mis à jour pour faire apparaître nos modifications (voir la figure suivante).
Vous pouvez constater que le designer s’est mis à jour pour faire apparaître nos modifications (voir la figure suivante).
Ouvrez maintenant le fichier de code behind et modifiez la méthode
Button_Tap_1
pour avoir :
private void Button_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
Resultat.Text = "Bonjour " + Nom.Text;
}
Nous pouvons dès à présent démarrer notre application en appuyant sur F5. L’émulateur se lance et nous voyons apparaître les nouvelles informations sur l’écran (voir la figure suivante).
La
souris va ici permettre de simuler le « toucher » avec le doigt lorsque
nous cliquons. Cliquons donc dans la zone de texte et nous voyons
apparaître un clavier virtuel à l’intérieur de notre application (voir
la figure suivante).
Ce clavier virtuel s’appelle le SIP (pour Soft Input Panel)
et apparait automatiquement quand on en a besoin, notamment dans les
zones de saisie, nous y reviendrons. Saisissons une valeur dans la zone
de texte et cliquons sur le bouton Valider.
Nous voyons apparaître le résultat en rouge avec un magnifique message construit (voir la figure suivante).
Nous voyons apparaître le résultat en rouge avec un magnifique message construit (voir la figure suivante).
Et voilà, notre Hello World est terminé ! Chouette non ?
Pour quitter l’application, le plus simple est d’arrêter le débogueur de Visual Studio en cliquant sur le carré
Pour quitter l’application, le plus simple est d’arrêter le débogueur de Visual Studio en cliquant sur le carré
Stop
.L’interface en XAML
Alors, taper des choses sans rien comprendre, ça va un moment… mais là, il est temps de savoir ce que nous avons fait !
Nous
avons dans un premier temps fait des choses dans le XAML. Pour rappel,
le XAML sert à décrire le contenu de ce que nous allons voir à l’écran.
En fait, un fichier XAML correspond à une page. Une application peut
être découpée en plusieurs pages, nous y reviendrons plus tard. Ce que
nous avons vu sur l’émulateur est l’affichage de la page
MainPage
.
Donc,
nous avons utilisé le XAML pour décrire le contenu de la page. Il est
globalement assez explicite mais ce qu’il faut comprendre c’est que nous
avons ajouté des contrôles du framework .NET dans la page. Un contrôle
est une classe C# complète qui sait s’afficher, se positionner, traiter
des événements de l’utilisateur (comme le clic sur le bouton), etc. Ces
contrôles ont des propriétés et peuvent être ajoutés dans le XAML.
Par exemple, prenons la ligne suivante :
Par exemple, prenons la ligne suivante :
Text="Saisir votre nom" HorizontalAlignment="Center"
Nous demandons d’ajouter dans la page le contrôle TextBlock. Le contrôle
TextBlock
correspond à une zone de texte non modifiable. Nous positionnons sa propriété Text
à la chaine de caractères "Saisir votre nom". Ce contrôle sera aligné au centre grâce à la propriété HorizontalAlignment
positionnée à Center
.
En fait, j’ai dit que nous l’ajoutons dans la page, mais pour être plus
précis, nous l’ajoutons dans le contrôle StackPanel qui est lui-même
contenu dans le contrôle Grid
, qui est contenu dans la page. Nous verrons plus loin ce que sont ces contrôles.
Derrière, automatiquement, cette ligne de XAML entraîne la déclaration et l’instanciation d’un objet de type
Parfait ! Moins on en fait et mieux on se porte… et surtout il y a moins de risque d’erreurs.
TextBlock
avec les affectations de propriétés adéquates. Puis ce contrôle est ajouté dans le contrôle StackPanel
.
Tout ceci nous est masqué. Grâce au XAML nous avons simplement décrit
l’interface de la page et c’est Visual Studio qui s’est occupé de le
transformer en C#.Parfait ! Moins on en fait et mieux on se porte… et surtout il y a moins de risque d’erreurs.
Et c’est pareil pour tous les autres contrôles de la page, le
TextBlock
qui est une zone de texte non modifiable, le TextBox
qui est une zone de texte modifiable déclenchant l’affichage du clavier virtuel, le bouton, etc.
Vous l’aurez peut-être deviné, mais c’est pareil pour la page. Elle est déclarée tout en haut du fichier XAML :
x:Class="HelloWorld.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True"
C’est
d’ailleurs le conteneur de base du fichier XAML, celui qui contient
tous les autres contrôles. La page est en fait représentée par la classe
PhoneApplicationPage
qui est aussi un objet du framework .NET. Plus précisément, notre page est une classe générée qui dérive de l’objet PhoneApplicationPage
. Il s’agit de la class MainPage
située dans l’espace de nom HelloWorld, c’est ce que l’on voit dans la propriété :
x:Class="HelloWorld.MainPage"
On
peut s’en rendre compte également dans le code behind de la page où
Visual Studio a généré une classe partielle du même nom que le fichier
XAML et qui dérive de
PhoneApplicationPage
:
public partial class MainPage : PhoneApplicationPage
{
// Constructeur
public MainPage()
{
InitializeComponent();
}
private void Button_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
Resultat.Text = "Bonjour " + Nom.Text;
}
}
Pourquoi
partielle ? Parce qu’il existe un autre fichier dans votre projet. Ce
fichier est caché mais on peut l’afficher en cliquant sur le bouton en
haut de l’explorateur de solution (voir la figure suivante).
Et nous pouvons voir notamment un répertoire
obj
contenant un répertoire debug
contenant le fichier MainPage.g.i.cs
. Si vous l’ouvrez, vous pouvez trouver le code suivant :
public partial class MainPage : Microsoft.Phone.Controls.PhoneApplicationPage
{
internal System.Windows.Controls.Grid LayoutRoot;
internal System.Windows.Controls.StackPanel TitlePanel;
internal System.Windows.Controls.Grid ContentPanel;
internal System.Windows.Controls.TextBox Nom;
internal System.Windows.Controls.TextBlock Resultat;
private bool _contentLoaded;
/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void InitializeComponent()
{
if (_contentLoaded)
{
return;
}
_contentLoaded = true;
System.Windows.Application.LoadComponent(this, new System.Uri("/HelloWorld;component/MainPage.xaml", System.UriKind.Relative));
this.LayoutRoot = ((System.Windows.Controls.Grid)(this.FindName("LayoutRoot")));
this.TitlePanel = ((System.Windows.Controls.StackPanel)(this.FindName("TitlePanel")));
this.ContentPanel = ((System.Windows.Controls.Grid)(this.FindName("ContentPanel")));
this.Nom = ((System.Windows.Controls.TextBox)(this.FindName("Nom")));
this.Resultat = ((System.Windows.Controls.TextBlock)(this.FindName("Resultat")));
}
}
Il
s’agit d’une classe qui est générée lorsqu’on modifie le fichier XAML.
Ne modifiez pas ce fichier car il sera re-généré tout le temps. On peut
voir qu’il s’agit d’une classe
Nous voyons notamment qu’il a créé les deux variables suivantes :
MainPage
, du même nom que la propriété x:Class
de tout à l’heure, qui s’occupe de charger le fichier XAML et qui crée
des variables à partir des contrôles qu’il trouvera dedans.Nous voyons notamment qu’il a créé les deux variables suivantes :
internal System.Windows.Controls.TextBox Nom;
internal System.Windows.Controls.TextBlock Resultat;
Le nom de ces variables correspond aux propriétés
x:Name
des deux contrôles que nous avons créé :
x:Name="Nom"
x:Name="Resultat" Foreground="Red"
Ces
variables sont initialisées après qu’il ait chargé tout le XAML en
faisant une recherche à partir du nom du contrôle. Cela veut dire que
nous disposons d’une variable qui permet d’accéder au contrôle de la
page, par exemple la variable
Nous avons donc :
Nom
du type TextBox
. Je vais y revenir.Nous avons donc :
- Un fichier
MainPage.xaml
qui contient la description des contrôles - Un fichier généré qui contient une classe partielle qui dérive de
PhoneApplicationPage
et qui charge ce XAML et qui rend accessible nos contrôles via des variables - Un fichier de code behind qui contient la même classe partielle où nous pourrons écrire la logique de notre code
Remarquez qu’il existe également le fichier
MainPage.g.cs
qui correspond au fichier généré après la compilation. Nous ne nous
occuperons plus de ces fichiers générés, ils ne servent plus à rien.
Nous les avons regardés pour comprendre comment cela fonctionne.Le code-behind en C#
Revenons sur le code behind, donc sur le fichier
MainPage.xaml.cs
, nous avons :
public partial class MainPage : PhoneApplicationPage
{
// Constructeur
public MainPage()
{
InitializeComponent();
}
private void Button_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
Resultat.Text = "Bonjour " + Nom.Text;
}
}
On retrouve bien notre classe partielle qui hérite des fonctionnalités de la classe
Vous aurez compris ici que ce sont les propriétés
PhoneApplicationPage
. Regardez à l’intérieur de la méthode Button_Tap_1
,
nous utilisons les fameuses variables que nous n’avons pas déclaré
nous-même mais qui ont été générées… Ce sont ces variables qui nous
permettent de manipuler nos contrôles et en l’occurrence ici, qui nous
permettent de modifier la valeur de la zone de texte non modifiable en
concaténant la chaine « Bonjour » à la valeur de la zone de texte
modifiable, accessible via sa propriété Text
.Vous aurez compris ici que ce sont les propriétés
Text
des TextBlock
et TextBox
qui nous permettent d’accéder au contenu qui est affiché sur la page.
Il existe plein d’autres propriétés pour ces contrôles comme la
propriété Foreground
qui permet de modifier la couleur du contrôle, sauf qu’ici nous l’avions positionné grâce au XAML :
x:Name="Resultat" Foreground="Red"
Chose que nous aurions également pu faire depuis le code behind :
private void Button_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
Resultat.Foreground = new SolidColorBrush(Colors.Red);
Resultat.Text = "Bonjour " + Nom.Text;
}
Sachez
quand même que d’une manière générale, on aura tendance à essayer de
mettre le plus de chose possible dans le XAML plutôt que dans le code
behind. La propriété
Foreground
ici a tout intérêt à être déclarée dans le XAML.Le contrôle Grid
Je
vais y revenir plus loin un peu plus loin, mais pour que vous ne soyez
pas complètement perdu dans notre Hello World, il faut savoir que la
Grid
est un conteneur.
Après
cet effort de traduction intense, nous pouvons dire que la grille sert à
contenir et à agencer d’autres contrôles. Dans notre cas, le code
suivant :
x:Name="LayoutRoot" Background="Transparent"
RowDefinitions
.
Height="Auto"
Height="*"
RowDefinitions
.
x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"
Text="MON APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"
Text="Hello World" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"
x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"
Text="Saisir votre nom" HorizontalAlignment="Center"
x:Name="Nom"
Content="Valider" Tap="Button_Tap_1"
x:Name="Resultat" Foreground="Red"
Défini une grille qui contient deux lignes. La première contient un contrôle
Nous aurons l’occasion d’en parler plus longuement plus tard donc je m’arrête là pour l’instant sur la grille.
StackPanel
,
nous allons en parler juste après. La seconde ligne contient une
nouvelle grille sans ligne ni colonne, qui est également composée d’un StackPanel
.Nous aurons l’occasion d’en parler plus longuement plus tard donc je m’arrête là pour l’instant sur la grille.
Le contrôle StackPanel
Ici c’est pareil, le contrôle
StackPanel
est également un conteneur. Je vais y revenir un peu plus loin
également mais il permet ici d’aligner les contrôles les uns en dessous
des autres. Par exemple, celui que nous avons rajouté contient un TextBlock
, un TextBox
, un bouton et un autre TextBlock
:
Text="Saisir votre nom" HorizontalAlignment="Center"
x:Name="Nom"
Content="Valider" Tap="Button_Tap_1"
x:Name="Resultat" Foreground="Red"
Nous pouvons voir sur le designer que les contrôles sont bien les uns en dessous des autres.
Nous avons donc au final, la page qui contient une grille, qui contient un
Nous avons donc au final, la page qui contient une grille, qui contient un
StackPanel
et une grille qui contiennent chacun des contrôles.Le contrôle TextBox
Le
contrôle TextBox est une zone de texte modifiable. Nous l’avons
utilisée pour saisir le prénom de l’utilisateur. On déclare ce contrôle
ainsi :
x:Name="Nom"
Lorsque
nous cliquons dans la zone de texte, le clavier virtuel apparait et
nous offre la possibilité de saisir une valeur. Nous verrons un peu plus
loin qu’il est possible de changer le type du clavier virtuel.
La valeur saisie est récupérée via la propriété
La valeur saisie est récupérée via la propriété
Text
du contrôle, par exemple ici je récupère la valeur saisie que je
concatène à la chaine Bonjour et que je stocke dans la variable resultat
:
string resultat = "Bonjour " + Nom.Text;
Inversement, je peux pré-remplir la zone de texte avec une valeur en utilisant la propriété
Text
, par exemple depuis le XAML :
x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"
x:Name="Nom" Text="Nicolas"
Ce qui donne la figure suivante.
La même chose est faisable en code behind, il suffit d’initialiser la propriété de la variable dans le constructeur de la page :
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
Nom.Text = "Nicolas";
}
}
Évidemment, il sera toujours possible de modifier la valeur pré-remplie grâce au clavier virtuel.
Le contrôle TextBlock
Le contrôle
TextBlock
représente une zone de texte non modifiable. Nous l’avons utilisé pour
afficher le résultat de notre Hello World. Il suffit d’utiliser sa
propriété Text
pour afficher un texte. Par exemple, le XAML suivant :
Text="Je suis un texte non modifiable de couleur rouge" Foreground="Red" FontSize="25"
affiche la fenêtre de prévisualisation présentée dans la figure suivante.
Je peux modifier la couleur du texte grâce à la propriété
Foreground
. C’est la même chose pour la taille du texte, modifiable via la propriété FontSize
.
Nous pouvons remarquer que le texte que j’ai saisi dépasse de l’écran
et que nous ne le voyons pas en entier. Pour corriger ça, j’utilise la
propriété TextWrapping
que je positionne à Wrap
:
Text="Je suis un texte non modifiable de couleur rouge" Foreground="Red" FontSize="25" TextWrapping="Wrap"
Comme nous l’avons déjà fait, il est possible de modifier la valeur d’un
TextBlock
en passant par le code-behind :
Resultat.Text = "Bonjour " + Nom.Text;
Les événements
Il
s’agit des événements sur les contrôles. Chaque contrôle est capable de
lever une série d’événements lorsque cela est opportun. C’est le cas
par exemple du contrôle bouton qui est capable de lever un événement
lorsque nous tapotons dessus (ou que nous cliquons avec la souris). Nous
l’avons vu dans l’exemple du Hello World, il suffit de déclarer une
méthode que l’on associe à l’événement, par exemple :
Content="Valider" Tap="Button_Tap_1"
qui permet de faire en sorte que la méthode
Button_Tap_1
soit appelée lors du clic sur le bouton. Rappelez-vous, dans notre Hello World, nous avions la méthode suivante :
private void Button_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
Resultat.Text = "Bonjour " + Nom.Text;
}
Il
est également possible de s’abonner à un événement via le code behind,
il suffit d’avoir une variable de type bouton, pour cela donnons un nom à
un bouton :
x:Name="UnBouton" Content="Cliquez-moi"
Et d’associer une méthode à l’événement de clic :
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
UnBouton.Tap += UnBouton_Tap;
}
void UnBouton_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
throw new NotImplementedException();
}
}
Il existe beaucoup d’événements de ce genre, par exemple la case à cocher (
CheckBox
) permet de s’abonner à l’événement qui est déclenché lorsqu’on coche la case :
Content="Cochez-moi" Checked="CheckBox_Checked_1"
Avec la méthode :
private void CheckBox_Checked_1(object sender, RoutedEventArgs e)
{
}
Il
existe énormément d’événement sur les contrôles, mais aussi sur la
page, citons encore par exemple l’événement qui permet d’être notifié
lors de la fin du chargement de la page :
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
}
Nous aurons l’occasion de voir beaucoup d’autres événements tout au long de ce cours.
Remarquez que les événements sont toujours construits de la même façon. Le premier paramètre est du type
object
et représente le contrôle qui a déclenché l’événement. En l’occurrence, dans l’exemple suivant :
Content="Valider" Tap="Button_Tap_1"
Nous pouvons accéder au contrôle de cette façon :
private void Button_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
Button bouton = (Button)sender;
bouton.Content = "C'est validé !";
}
Le second paramètre est, quant à lui, spécifique au type d’événement et peut fournir des informations complémentaires.
Le bouton
Revenons à présent rapidement sur le bouton, nous l’avons vu il n’est pas très compliqué à utiliser. On utilise la propriété
Content
pour mettre du texte et il est capable de lever un événement lorsqu’on clique dessus, grâce à l’événement Tap
. Le bouton possède également un événement Click
qui fait la même chose et qui existe encore pour des raisons de compatibilité avec Silverlight.
Il
est également possible de passer des paramètres à un bouton. Pour un
bouton tout seul, ce n’est pas toujours utile, mais dans certaines
situations cela peut être primordial.
Dans l’exemple qui suit, j’utilise deux boutons qui ont la même méthode pour traiter l’événement de clic sur le bouton :
Dans l’exemple qui suit, j’utilise deux boutons qui ont la même méthode pour traiter l’événement de clic sur le bouton :
Content="Afficher" Tap="Button_Tap" CommandParameter="Nicolas"
Content="Afficher" Tap="Button_Tap" CommandParameter="Jérémie"
x:Name="Resultat" Foreground="Red"
C’est la propriété
CommandParameter
qui me permet de passer un paramètre. Je pourrais ensuite l’utiliser dans mon code behind :
private void Button_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
Button bouton = (Button)sender;
bouton.IsEnabled = false;
Resultat.Text = "Bonjour " + bouton.CommandParameter;
}
J’utilise ainsi le paramètre
CommandParameter
pour récupérer le prénom de la personne à qui dire bonjour (voir la figure suivante).
Remarquez au passage l’utilisation de la propriété
IsEnabled
qui permet d’indiquer si un contrôle est activé ou pas. Si un bouton est désactivé, il ne pourra pas être cliqué.Et Silverlight dans tout ça ?
Vous avez remarqué que j’ai parlé de Silverlight et de XAML. Quelle différence ?
Pour
bien comprendre, Silverlight était utilisé pour développer avec les
versions 7 de Windows Phone. On utilise par contre le XAML/C# pour
développer pour la version 8. En fait, grosso modo c’est la même chose.
XAML
est l’évolution de Silverlight. Si vous avez des connaissances en
Silverlight, vous vous êtes bien rendu compte que ce qu’on appelle
aujourd’hui XAML/C#, c’est pareil.
Il s’agit juste d’un changement de vocabulaire afin d’unifier les développements utilisant du code XAML pour définir l’interface d’une application, qu’elle soit Windows Phone ou Windows …
Il s’agit juste d’un changement de vocabulaire afin d’unifier les développements utilisant du code XAML pour définir l’interface d’une application, qu’elle soit Windows Phone ou Windows …
Ce qui est valable avec Silverlight l'est aussi avec XAML/C#, et inversement proportionnel.
- Le XAML permet de décrire l’interface de nos pages.
- Le code behind permet d’écrire le code C# de la logique de nos pages.
- On utilise des contrôles dans nos interfaces, comme le bouton ou la zone de texte.
- Les contrôles sont des classes complètes qui savent s’afficher, se positionner ou réagir à des événements utilisateurs, comme le clic sur un bouton.
Aucun commentaire:
Enregistrer un commentaire