Mango Jump Start 抜粋:巡回ナビゲーションのハンドリング

Mango Jump Start (03)より抜粋

Windows Phone アプリケーションにおいて、アプリケーションを正常に終了されるケースはメインページにおいて、ユーザがバックキーを押下した場合のみです。

ここで、以下のような巡回するページナビゲーションのケースを考えてみます。

メインページ:ページ2 へのリンクボタンを持つ
ページ2:ページ3へのリンクボタンを持つ
ページ3:メインページへのリンクボタン(HOMEボタン)を持つ

上記のケースでユーザが

メインページ(ページ2へのリンクボタン押下)
 ↓
ページ2(ページ3へのリンクボタン押下)
 ↓
ページ3(HOMEボタン押下)
 ↓
メインページ

と画面遷移したとします。

するとナビゲーションスタックは以下のようになります。

[メインページ] ←今ココ
[ページ3]
[ページ2]
[メインページ]

ここでユーザがバックキーを押下した場合、ユーザが期待する挙動としては、「メインページに戻ってきてバックキーを押した」ので多くの場合はアプリケーションの終了になります。しかしデフォルトの挙動では、ナビゲーションスタックに従いアプリケーションの画面がページ3に戻るだけです。

[メインページ]
[ページ3] ←今ココ
[ページ2]
[メインページ] ←ここでバックキーを押さないとアプリは終了しない

そこでページ3のホームボタンのナビゲーションUriに「ページ3から戻ってきた」と言うキーを設定し、メインページのOnNavigatedToイベントにおいてページ3から戻ってきている場合は、ナビゲーションスタックをクリアにし、バックキーでアプリケーションが終了するにように制御してあげます。

ページ3:「ページ3から戻ってきた」と言うキー(?HomeFromThird=true)を設定しておく。

<HyperlinkButton Content="HOME" NavigateUri="/MainPage.xaml?HomeFromThird=true" />

メインページ:キーが設定されている場合は、ナビゲーションスタックをクリアしてあげる。

protected override void OnNavigatedTo(NavigationEventArgs args)
{
    base.OnNavigatedFrom(args);

    if (args.NavigationMode == System.Windows.Navigation.NavigationMode.New &&
        NavigationContext.QueryString.ContainsKey("HomeFromThird"))
    {
        NavigationService.RemoveBackEntry();  //第3ページをナビゲーションスタックから削除
        NavigationService.RemoveBackEntry();  //第2ページをナビゲーションスタックから削除
        NavigationService.RemoveBackEntry();  //最初のメインページをナビゲーションスタックから削除
    }
}

ちなにみNavigationService.RemoveBackEntry()はWindows Phone 7.5(VS上は7.1)から追加されており7.0の場合は別途対処する必要があります。詳細は以下を参照してください。

Solving Circular Navigation in Windows Phone Silverlight Applications