1.Introduction▲
Windows Phone 7 (WP7) est la nouvelle plateforme de développement de Microsoft destinée aux smartphones.
Cet article est le quatrième d'une série traitant du développement d'applications sous WP7.
Dans ce tutoriel nous allons voir comment naviguer entre les pages d'une application Silverlight pour Windows Phone 7. Nous verrons également que le bouton « Back » du téléphone s'interface parfaitement avec le framework de navigation de Silverlight pour WP7. Nous verrons enfin comment faire passer des informations entre les pages.
Si besoin, ou en guise d'introduction, n'hésitez pas à aller consulter les articles précédents :
2.La navigation au sein d'une application WP7▲
Les Windows Phones disposent d'un bouton « Back ».
Celui-ci, comme son nom le suggère, permet de revenir à la page précédente. Maîtriser la navigation entre les pages devient un besoin fondamental pour accompagner celle de l'utilisateur.
Silverlight dispose de plusieurs outils pour aider à la navigation entre les pages. C'est tout naturellement que Silverlight pour Windows Phone 7 fournit des moyens de navigation adaptés aux téléphones.
2.1.L'HyperlinkButton▲
Pour voir comment fonctionne la navigation, commençons par créer une application WP7 (Fichier -> Nouveau Projet -> Application Windows Phone).
Comme le Silverlight classique, Silverlight pour Windows Phone dispose d'un contrôle HyperlinkButton qui offre la possibilité de naviguer entre les pages. Ajoutons-en deux sur la page principale :
<Grid
x
:
Name
=
"LayoutRoot"
Background
=
"Transparent"
>
<Grid.RowDefinitions>
<RowDefinition
Height
=
"Auto"
/>
<RowDefinition
Height
=
"*"
/>
</Grid.RowDefinitions>
<StackPanel
x
:
Name
=
"TitlePanel"
Grid.
Row
=
"0"
Margin
=
"12,17,0,28"
>
<TextBlock
x
:
Name
=
"PageTitle"
Text
=
"Démo Navigation"
Margin
=
"9,-7,0,0"
FontSize
=
"55"
/>
</StackPanel>
<Grid
x
:
Name
=
"ContentPanel"
Grid.
Row
=
"1"
Margin
=
"12,0,12,0"
>
<StackPanel>
<HyperlinkButton
NavigateUri
=
"/NavigationState.xaml"
Content
=
"Navigation State"
/>
<HyperlinkButton
NavigateUri
=
"/NavigationQuery.xaml"
Content
=
"Navigation Query"
/>
</StackPanel>
</Grid>
</Grid>
On peut voir ici qu'il est très simple de faire un lien vers d'autres pages en utilisant l'attribut NavigateUri de l'HyperlinkButton.
Il suffit d'indiquer l'emplacement d'une page XAML.
Créons les deux pages NavigationState.xaml et NavigationQuery.xaml. Celles-ci seront identiques à part au niveau du titre qui nous permettra de les différencier. Puis lançons l'application (F5).
On peut voir que lorsqu'on clique sur « Navigation State », alors on change de page. Tout à fait naturellement, lorsque l'on souhaite revenir à la page précédente, on peut cliquer sur le bouton « Back » du téléphone. On peut faire de même avec le lien « Navigation Query ».
Et voilà, nous naviguons entre les pages de notre application en n'ayant presque rien fait, à part ajouter un contrôle HyperlinkButton.
2.2.Retour en arrière▲
Modifions une des pages, par exemple NavigationState pour rajouter un bouton :
<Button
Content
=
"Retour"
Click
=
"Button_Click"
/>
et traitons l'événement du clic sur le bouton côté code behind :
private
void
Button_Click
(
object
sender,
System.
Windows.
RoutedEventArgs e)
{
NavigationService.
GoBack
(
);
}
Comme on peut s'en douter, dans la mesure où c'est quand même assez explicite, en cliquant sur ce bouton, on revient à la page précédente, comme si on avait appuyé sur le bouton « Back ».
La classe NavigationService contient toutes les méthodes qu'il faut pour gérer la navigation.
2.3.Le service de navigation▲
La classe NavigationService permet aussi de naviguer entre les pages par code, avec notamment sa fonction Navigate().
Illustrons ce comportement en créant sur la page NavigationState une ListBox où nous affectons la propriété ItemsSource à une liste d'articles.
Pour ce faire, créons un semblant de modèle via les classes suivantes :
public
class
Article
{
public
string
Nom {
get
;
set
;
}
public
DateTime DatePublication {
get
;
set
;
}
public
string
Contenu {
get
;
set
;
}
}
et
public
static
class
Model
{
public
static
List<
Article>
GetArticles
(
)
{
List<
Article>
articles =
new
List<
Article>(
);
articles.
Add
(
new
Article {
Nom =
"Introduction WP7"
,
DatePublication =
new
DateTime
(
2010
,
11
,
15
),
Contenu =
"Cet article constitue une introduction à WP7"
}
);
articles.
Add
(
new
Article {
Nom =
"Listbox WP7"
,
DatePublication =
new
DateTime
(
2010
,
20
,
11
),
Contenu =
"Cet article parle de la ListBox WP7 et de l'isolated storage"
}
);
articles.
Add
(
new
Article {
Nom =
"Contrôle Pivot WP7"
,
DatePublication =
new
DateTime
(
2010
,
12
,
5
),
Contenu =
"Cet article explore le contrôle Pivot"
}
);
articles.
Add
(
new
Article {
Nom =
"Navigation WP7"
,
DatePublication =
new
DateTime
(
2010
,
12
,
30
),
Contenu =
"Cet article permet de découvrir la navigation WP7"
}
);
return
articles;
}
}
Ici, on construit simplement une liste très sommaire d'articles.
2.3.1.Utiliser le dictionnaire d'état pour faire transiter des informations▲
La page NavigationState.xaml contiendra :
<Grid
x
:
Name
=
"LayoutRoot"
Background
=
"Transparent"
>
<Grid.RowDefinitions>
<RowDefinition
Height
=
"Auto"
/>
<RowDefinition
Height
=
"*"
/>
</Grid.RowDefinitions>
<StackPanel
x
:
Name
=
"TitlePanel"
Grid.
Row
=
"0"
Margin
=
"12,17,0,28"
>
<TextBlock
x
:
Name
=
"PageTitle"
Text
=
"Navigation State"
Margin
=
"9,-7,0,0"
FontSize
=
"55"
/>
</StackPanel>
<Grid
x
:
Name
=
"ContentPanel"
Grid.
Row
=
"1"
Margin
=
"12,0,12,0"
>
<ListBox
x
:
Name
=
"listBox"
SelectionChanged
=
"listBox_SelectionChanged"
>
<ListBox.ItemTemplate>
<DataTemplate>
<Border
CornerRadius
=
"10"
Margin
=
"50 30 30 30"
Background
=
"Gray"
Width
=
"300"
Height
=
"100"
>
<TextBlock
Text
=
"{Binding Nom}"
VerticalAlignment
=
"Center"
HorizontalAlignment
=
"Center"
/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
et dans le code behind nous aurons :
public
partial
class
NavigationState :
PhoneApplicationPage
{
private
ObservableCollection<
Article>
articles;
public
NavigationState
(
)
{
InitializeComponent
(
);
articles =
new
ObservableCollection<
Article>(
);
foreach
(
Article article in
Model.
GetArticles
(
))
{
articles.
Add
(
article);
}
listBox.
ItemsSource =
articles;
}
private
void
listBox_SelectionChanged
(
object
sender,
SelectionChangedEventArgs e)
{
Article currentArticle =
(
Article)listBox.
SelectedItem;
PhoneApplicationService.
Current.
State[
"Article"
]
=
currentArticle;
NavigationService.
Navigate
(
new
Uri
(
"/ArticleView.xaml"
,
UriKind.
Relative));
}
}
On construit une ObservableCollection avec la liste d'articles que l'on affecte à la propriété ItemsSource de la ListBox.
Dans l'événement de changement de sélection de la ListBox, nous récupérons l'élément sélectionné et le stockons dans le dictionnaire d'état de l'application. Puis nous appelons le service de navigation en lui communiquant l'URL de la page à afficher.
Comme vous l'aurez compris, nous utilisons le dictionnaire d'état de l'application pour communiquer un contexte à la page vers laquelle nous allons naviguer. C'est une solution, sachant qu'il y en a d'autres, dont une que nous allons explorer plus loin.
Créons désormais la page ArticleView.xaml avec le xaml suivant :
<Grid
x
:
Name
=
"LayoutRoot"
Background
=
"Transparent"
>
<Grid.RowDefinitions>
<RowDefinition
Height
=
"Auto"
/>
<RowDefinition
Height
=
"*"
/>
</Grid.RowDefinitions>
<StackPanel
x
:
Name
=
"TitlePanel"
Grid.
Row
=
"0"
Margin
=
"12,17,0,28"
>
<TextBlock
x
:
Name
=
"ApplicationTitle"
Text
=
"Consultation d'article :"
Style
=
"{StaticResource PhoneTextNormalStyle}"
/>
<TextBlock
x
:
Name
=
"PageTitle"
Margin
=
"9,-7,0,0"
Style
=
"{StaticResource PhoneTextTitle1Style}"
/>
</StackPanel>
<Grid
x
:
Name
=
"ContentPanel"
Grid.
Row
=
"1"
Margin
=
"12,0,12,0"
>
<StackPanel>
<TextBlock
x
:
Name
=
"date"
/>
<TextBlock
x
:
Name
=
"contenu"
/>
</StackPanel>
</Grid>
</Grid>
Pour récupérer le contexte, nous allons surcharger la méthode OnNavigatedTo. C'est la méthode qui est appelée lorsque l'on navigue sur une page.
protected
override
void
OnNavigatedTo
(
NavigationEventArgs e)
{
Article currentArticle =
(
Article)PhoneApplicationService.
Current.
State[
"Article"
];
PageTitle.
Text =
currentArticle.
Nom;
date.
Text =
currentArticle.
DatePublication.
ToShortDateString
(
);
contenu.
Text =
currentArticle.
Contenu;
base
.
OnNavigatedTo
(
e);
}
Nous récupérons la sélection depuis le dictionnaire d'état et affichons le contenu dans la page.
2.3.2.Utilisation de la query string▲
Une autre façon de faire est d'utiliser la query string.
Pour illustrer ce fonctionnement, modifions la page NavigationQuery.xaml qui est quasiment la même que la page NavigationState.xaml au détail près que le titre est différent et que la méthode listBox_SelectionChanged du code behind sera :
private
void
listBox_SelectionChanged
(
object
sender,
SelectionChangedEventArgs e)
{
NavigationService.
Navigate
(
new
Uri
(
"/ArticleView2.xaml?index="
+
listBox.
SelectedIndex,
UriKind.
Relative));
}
Ici, on utilise la query string pour passer la valeur de l'index de l'élément sélectionné.
La page ArticleView2.xaml est exactement la même que ArticleView.xaml à la différence près que l'on récupère les informations différemment, depuis la méthode OnNavigatedTo :
protected
override
void
OnNavigatedTo
(
NavigationEventArgs e)
{
string
indexStr;
if
(
NavigationContext.
QueryString.
TryGetValue
(
"index"
,
out
indexStr))
{
int
index =
int
.
Parse
(
indexStr);
Article currentArticle =
Model.
GetArticles
(
)[
index];
PageTitle.
Text =
currentArticle.
Nom;
date.
Text =
currentArticle.
DatePublication.
ToShortDateString
(
);
contenu.
Text =
currentArticle.
Contenu;
}
base
.
OnNavigatedTo
(
e);
}
Ici on utilise le contexte de navigation (NavigationContext) pour récupérer la valeur que nous avons transmise dans la query string.
Une fois cette valeur récupérée, il ne reste plus qu'à accéder à l'élément de la liste à l'index adéquat et nous pouvons afficher notre contenu.
Nous avons pu voir ainsi deux façons différentes de naviguer entre les pages, via le contrôle HyperlinkButton et via le NavigationService. Puis nous avons vu deux façons différentes de passer des informations entre les pages, via la query string et via le dictionnaire d'état de l'application.
3.Démonstration de l'application▲
Pour se rendre compte de la navigation, regardons cette vidéo :
Dans un premier temps, je clique sur un HyperLinkButton et je change de page.
Je clique sur « Back » et je reviens à la page précédente.
Je peux cliquer sur un élément de la ListBox et je suis redirigé vers une autre page où je peux voir le contenu d'un article.
Encore une fois, un clic sur le bouton « Back » permet de revenir à la page précédente.
Cliquons encore une fois sur le bouton « Back » et nous pouvons observer que l'application WP7 gère bien la pile de navigation.
4.Téléchargements▲
Vous pouvez télécharger ici les sources du projet : version rar (91 Ko), version zip (100 Ko).
5.Conclusion▲
Nous avons donc vu dans ce tutoriel comment créer une application Windows Phone 7 qui tire parti du framework de navigation Silverlight adapté à WP7.
Nous avons dans un premier temps utilisé le contrôle HyperLinkButton. Puis nous avons utilisé la classe NavigationService pour naviguer en arrière et naviguer vers une autre page. Enfin, nous avons vu comment faire passer des informations entre les pages via le dictionnaire d'état et par la query string.
J'espère que ce tutoriel a pu vous être utile et vous a donné envie de vous perfectionner dans la création d'applications pour Windows Phone 7.
Remerciements▲
Je remercie les membres de l'équipe Dotnet pour leurs relectures attentives du document et leurs remarques ainsi que ClaudeLELOUP pour sa relecture orthographique.
Contact▲
Si vous constatez une erreur dans le tutoriel, dans le code source, dans la programmation ou pour toute information, n'hésitez pas à me contacter par le forum.