locked
他のページに遷移したあと、自ページを終了させたい

    質問

  • はじめまして。 tk_at_jibe (川崎) と申します。

    Windows 関連の開発全てにおいて素人なので、間抜けな質問をしてしまいますが、ご容赦ください。

     

    Windows Phone 7 用アプリのページ (PhoneApplicationPageのインスタンス) から他のページへ遷移したあと、自ページを終了させるにはどうしたらよいのでしょうか? 次のコードにおいて、Navigate() メソッド呼び出しのあとに何かすればいいのではないかと想像しているのですが、何をすればいいのかわからずにいます。

     

    namespace MyApp

    {

        public partial class PageA : PhoneApplicationPage

        {

            ......

            protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)

            {

                NavigationService.Navigate(new Uri("/PageB.xaml", UriKind.Relative));

                // PageB.xaml に遷移したあと、PageX は終了したい(もう使わない)のですけど、

                // どうしたらいいのでしょうか? PageB で Back ボタンを押したときに PageA に

                // 戻らないという動作を希望しているのですが・・・。

            }

    }

     

    教えていただけると助かります。よろしくお願いいたします。

    tk_at_jibe

    • 移動 Mike Wang (MSCS) 2012年10月2日 10:56 (移動元:Windows Phone 7 How-to)
    2011年4月15日 13:10

すべての返信

  • こんにちは、tmytです。

     

    調べてみましたが、PCのSilverlightでは NavigationService.RemoveBackEntry() というメソッドがサポートされていて、このメソッドを呼び出すことによって履歴のクリアが実行できます。
    ですが、このメソッドはWindowsPhone7では削除されており、呼び出すことができません。そのため履歴を削除そのものが行えないようです。

    これはあくまで想像ですが、WindowsPhone7ではページツリーを途中で切るのは推奨されないのではないでしょうか。

    NavigationServiceからヒストリの削除が実行できないので、代わり?にNavigationServiceにイベントハンドラを追加してBackを無効化する方法はあります。

    namespace WindowsPhonePanoramaApplication1
    {
      public partial class Page1 : PhoneApplicationPage
      {
        public Page1()
        {
          InitializeComponent();
        }
    
        void NavigationService_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
        {
          if (e.NavigationMode == System.Windows.Navigation.NavigationMode.Back)
          {
            e.Cancel = true;
          }
        }
    
        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
          NavigationService.Navigating += new System.Windows.Navigation.NavigatingCancelEventHandler(NavigationService_Navigating);
    
        }
      }
    }
    
    ただし、この方法だと戻る処理がそもそも無効になってしまうので、アプリケーションの終了ができなくなるため、このままではAppHubの審査を通過できないとおもいます。

    2011年4月15日 14:20
  • CH3COOH(酢酸)です。

    画面遷移時に履歴を消す方法は判りませんでした。

    MainPage -> Page1 -> Page2 と画面遷移していき、
    Page2でBackボタンを押下した際にMainPageまで戻れる方法があるのか?
    ・・という質問でよければご回答出来ると思います。

     

    MainPage.xaml.cs

     public partial class MainPage : PhoneApplicationPage
     {
      // Constructor
      public MainPage()
      {
       InitializeComponent();
      }
    
      private void button1_Click(object sender, RoutedEventArgs e)
      {
       NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.Relative));
      }
     }
    

     

    Page1.xaml.cs

     public partial class Page1 : PhoneApplicationPage
     {
      public Page1()
      {
       InitializeComponent();
      }
    
      bool isBackFlag = false;
    
      protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
      {
       if (isBackFlag) NavigationService.GoBack();
       base.OnNavigatedTo(e);
       isBackFlag = true;
      }
    
      private void button1_Click(object sender, RoutedEventArgs e)
      {
       NavigationService.Navigate(new Uri("/Page2.xaml", UriKind.Relative));
      }
     }
    
    

     

    Page2.xaml.cs

     public partial class Page2 : PhoneApplicationPage
     {
      public Page2()
      {
       InitializeComponent();
      }
     }
    

     

    一度、上記の試して頂けないでしょうか。

    この方法は途中でロック画面などアプリが一旦終了してしまった場合に使えませんので、
    Isolated Storageなどにフラグを保存しておく必要があるかもしれません。

    tmytさんも言及されておりますが、Marketplaceに並べるアプリを開発されている場合は、
    Windows Phone 7 Application Certification Requirementsの
    「5.2.4 Use of Back Button」に抵触しないようお気をつけください。


    • 編集済み Kenji Wada 2011年4月15日 15:14 コードがくっついていて見難い為間隔をあけました
    • 回答の候補に設定 高橋 忍Microsoft employee 2011年8月23日 17:01
    2011年4月15日 15:12
  • CH3COOH(酢酸)です。

    追記で申し訳有りません。
    Windows Phone Developer Blogの方に以下の記事が掲載されておりました。ご参照ください。

    http://windowsteamblog.com/windows_phone/b/wpdev/archive/2010/12/13/solving-circular-navigation-in-windows-phone-silverlight-applications.aspx

    2011年4月15日 16:13
  • tmyt さん、

    お返事ありがとうございます。 私、Silverlight 自体も初心者なもので、よく知らなかったのですが、PC 版と Windows Phone 版では差異があるのですね。 Android でいうところの Activity.finish() のようなメソッド (現在表示している画面単位をクローズするメソッド) が、PhoneApplicationPage もしくは NavigationService にあるのではないかと期待していたのですが、そういうものはないようですね。みなさん、どのようにプログラミングされているのでしょうか? そもそも私がやろうとしている「起動処理中の one time の使い捨てページ」のようなことは、みなさんやらない、ということかもしれませんが・・・。
    2011年4月18日 16:54
  • CH3COOH(酢酸)さん、

    お返事ありがとうございます。Windows Phone 7 Application Certification Requirements なるものがあって、Back ボタンに対する要求事項もあるのですね。全く知りませんでした(汗)。

    教えていただいた URL にある記事には「With the current version of Windows Phone, you can't manipulate the back-stack; that is, you don't have any APIs to remove pages from the application's back-stack.」と明確に書いてありますね。記事のライターの方は、ページのループを避けるために、NonLinearNavigationService クラスを提供してくださっていますね。でも、コメント欄を見ると、NonLinearNavigationService がうまくいかないケースもあるようですから、NonLinearNavigationService を盲目的に使用するのではなく、ソースコードからエッセンスを抜き出して自分用に改良する必要があるかもしれません。ちょっと調査してみようと思います。
    2011年4月18日 16:55
  • 当初、起動処理中を示すページを表示し、条件に従って遷移先のページを選んでそのページに遷移し、それに伴って起動処理中のページは破棄する、ということをおこなおうとしていたのですが、そういうこと (ページを使い捨て感覚で利用すること) は、Windows Phone のプログラミングでは、よくない設計のようですね。

     

    しかし、同じようなことを考えている人が少なからずいるようで、そういう人たちのために、 Introducing the concept of "Places" というブログが書かれたように思えます。

     

    http://blogs.msdn.com/b/ptorr/archive/2010/08/28/introducing-the-concept-of-places.aspx

     

    Place には PageApplicationPage を割り当てるけど、Place でないもの (スプラッシュスクリーンやログイン画面など) は PageApplicationPage 以外 (Popup など) で実装し、ナビゲーションが発生しないようにする (BACK ボタンの処理単位にならないようにする) という実装が推奨されているようですね。

    2011年4月19日 9:09
  • こんばんは、MOTO SQUAREです。

    最新の開発環境であるWPDT(7.1β)では、NavigationService.RemoveBackEntry()がサポートされるようになりました。
    このため、tk_at_jibeさんの仰るような「ページを使い捨て感覚で利用する」ことも可能になりそうです。

    なお「Windows Phone 7 Application Certification Requirements」はまだ更新されていないようですので、
    はやくWP7.1が正式に対応されるようになるといいですよね!
    2011年5月28日 13:56