kazuakix の日記

Windows Phone とか好きです

セカンダリ タイルからの起動を判別する方法 (3)

もう少し続きます。

昨日の記事に対して @KatsuYuzu さんと @biac さんから指摘を頂きました。

はい。宿題の内容を勘違いしていました。正しくは「いきなりサブ ページから起動した場合でも、戻るボタンで メインページに戻るように」という事ですね。(よく考えたらメイン ページに行くのって普通の動作ですもんね)

という訳で本題。
戻るボタンを有効にするためにページのナビゲーション履歴を直接書き換える方法です。
Silverlight の頃は NavigationService というクラスを使っていたような気がするのですが、 Windows ランタイムでは Frame.BackStack で履歴を操作します。

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    Frame rootFrame = Window.Current.Content as Frame;

    if (rootFrame == null)
    {
        // 省略
    }

    if (rootFrame.Content == null)
    {
        // 省略
        //if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
        //{
        //    throw new Exception("Failed to create initial page");
        //}
    }

    if (string.IsNullOrEmpty(e.Arguments))
    {
        rootFrame.Navigate(typeof(MainPage), null);
    }
    else
    {
        // メイン ページのナビゲーション履歴を追加
        rootFrame.BackStack.Add(new PageStackEntry(typeof(MainPage), null, null));
        rootFrame.Navigate(typeof(BlankPage), e.Arguments);
    }
    
    Window.Current.Activate();
}

昨日までと同じようにパラメーターがあればセカンダリ タイルからの起動と決めつけています。
また、アプリがバックグラウンドで実行中に通常起動された場合でも問答無用でメイン ページに遷移しています。(本当は何もせずに即座に再開するのがいいと思います)

続いて呼び出された側のサブ ページでは戻るボタンを拾ってナビゲーション履歴を遡るようにしています。(ちなみに Windows Phone のときだけ必要になります)

public BlankPage()
{
    this.InitializeComponent();

#if WINDOWS_PHONE_APP
        Windows.Phone.UI.Input.HardwareButtons.BackPressed += OnBackPressed;
#endif
}

void OnBackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
    if (this.Frame.CanGoBack)
    {
        e.Handled = true;
        this.Frame.GoBack();
    }
}

このあたりの処理はサブ ページを「空のページ」ではなく「基本ページ」として作成しておけば勝手によろしくやってくれるので便利です。