Windows Phone 7エミュレーターでは、ハードウェアの戻るボタンが押されたときのデフォルトの動作は、現在のアプリケーションを閉じることです。このデフォルトの動作をオーバーライドして、アプリケーションの前のページに移動するようにします。
いくつかの調査の後、次のようにOnBackKeyPressメソッドをオーバーライドすることでこれを行うことができるはずです:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
// do some stuff ...
// cancel the navigation
e.Cancel = true;
}
ただし、[戻る]ボタンをクリックしても、アプリケーションは閉じます。上記のメソッドにブレークポイントを設定すると、ブレークポイントが呼び出されないことがわかります。アプリケーションの終了コードに別のブレークポイントがあり、このブレークポイントisがヒットします。
[戻る]ボタンを傍受するために他に必要なことはありますか?
Navigate
メソッドを使用してアプリケーション内のページ間を移動しない限り、OnBackKeyPressメソッドをオーバーライドしてバックキーをインターセプトすることはできないようです。
以前のナビゲーション方法は、次のようにルートビジュアルを変更することでした。
App.Current.RootVisual = new MyPage();
つまり、すべてのページをメモリに保存できるため、ページに保存されているデータをキャッシュする必要がありません(一部のデータはネット経由で収集されます)。
ここで、実際にページフレームでNavigateメソッドを使用する必要があるようです。これにより、移動先のページの新しいインスタンスが作成されます。
(App.Current.RootVisual as PhoneApplicationFrame).Navigate(
new Uri("/MyPage.xaml", UriKind.Relative));
このメソッドを使用してナビゲートを開始したら、質問で説明されている方法で戻るボタンの処理をオーバーライドできます...
デフォルトのバックキーの動作を望まない場合は、OnBackKeyPressのCancelEventArgsパラメーターでCancel = trueを設定します。私のページでは、戻るボタンをオーバーライドして、戻るのではなくWebブラウザコントロールを閉じました。
protected override void OnBackKeyPress(CancelEventArgs e)
{
if (Browser.Visibility == Visibility.Visible)
{
Browser.Visibility = Visibility.Collapsed;
e.Cancel = true;
}
}
この手法を使用して、目的の操作を行うことができました。これは、ウィンドウの内外にスライドするコントロールを非表示にしている間、戻るナビゲーションを防止することです。デフォルトでは、コントロールの可視性は折りたたまれています。ストーリーボードは、いつ表示または縮小されるかを制御するために使用されます。 XAMLのストーリーボード内:
_<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ControlScroller" Storyboard.TargetProperty="(UIElement.Visibility)">
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
_
次に、ページのコードで:
_protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
if(ControlScroller.Visibility == Visibility.Visible && StoryboardHideControlSlider.GetCurrentState() != ClockState.Active)
{
StoryboardHideControlSlider.Begin();
ContentGrid.IsHitTestVisible = true;
e.Cancel = true;
}
}
_
注:ContentScroller(グリッド)を非表示にするストーリーボードでは、KeyTimeが "00:00:01"に設定されます。これは、スライドして(およびフェードアウトして)表示されないように見えるようにするためです。
注2:ifステートメントにStoryboardHideControlSlider.GetCurrentState() != ClockState.Active
が含まれる理由は、ユーザーが[戻る]ボタンを2回押してもストーリーボードが完了しなかった場合に、再度実行されるためです。これにより、戻るボタンで前のページに戻るナビゲーションをキャンセルできなくなります。つまり、ストーリーボードがアクティブな場合、コードはユーザーが既に非表示にしたことを「認識」しており、前のページに戻るつもりです。 (まあ、少なくともそれは彼らが得ようとしている振る舞いです...そして彼らはアニメーションを二度見ません)!