web-dev-qa-db-ja.com

Windows Phone 7で戻るボタンを処理する方法

Windows Phone 7エミュレーターでは、ハードウェアの戻るボタンが押されたときのデフォルトの動作は、現在のアプリケーションを閉じることです。このデフォルトの動作をオーバーライドして、アプリケーションの前のページに移動するようにします。

いくつかの調査の後、次のようにOnBackKeyPressメソッドをオーバーライドすることでこれを行うことができるはずです:

protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
    // do some stuff ...

    // cancel the navigation
    e.Cancel = true;
}

ただし、[戻る]ボタンをクリックしても、アプリケーションは閉じます。上記のメソッドにブレークポイントを設定すると、ブレークポイントが呼び出されないことがわかります。アプリケーションの終了コードに別のブレークポイントがあり、このブレークポイントisがヒットします。

[戻る]ボタンを傍受するために他に必要なことはありますか?

43
David_001

Navigateメソッドを使用してアプリケーション内のページ間を移動しない限り、OnBackKeyPressメソッドをオーバーライドしてバックキーをインターセプトすることはできないようです。

以前のナビゲーション方法は、次のようにルートビジュアルを変更することでした。

App.Current.RootVisual = new MyPage(); 

つまり、すべてのページをメモリに保存できるため、ページに保存されているデータをキャッシュする必要がありません(一部のデータはネット経由で収集されます)。

ここで、実際にページフレームでNavigateメソッドを使用する必要があるようです。これにより、移動先のページの新しいインスタンスが作成されます。

(App.Current.RootVisual as PhoneApplicationFrame).Navigate(
                                    new Uri("/MyPage.xaml", UriKind.Relative)); 

このメソッドを使用してナビゲートを開始したら、質問で説明されている方法で戻るボタンの処理をオーバーライドできます...

29
David_001

デフォルトのバックキーの動作を望まない場合は、OnBackKeyPressのCancelEventArgsパラメーターでCancel = trueを設定します。私のページでは、戻るボタンをオーバーライドして、戻るのではなくWebブラウザコントロールを閉じました。

    protected override void OnBackKeyPress(CancelEventArgs e)
    {
        if (Browser.Visibility == Visibility.Visible)
        {
            Browser.Visibility = Visibility.Collapsed;
            e.Cancel = true;
        }
    }
23
ManicBlowfish

この手法を使用して、目的の操作を行うことができました。これは、ウィンドウの内外にスライドするコントロールを非表示にしている間、戻るナビゲーションを防止することです。デフォルトでは、コントロールの可視性は折りたたまれています。ストーリーボードは、いつ表示または縮小されるかを制御するために使用されます。 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回押してもストーリーボードが完了しなかった場合に、再度実行されるためです。これにより、戻るボタンで前のページに戻るナビゲーションをキャンセルできなくなります。つまり、ストーリーボードがアクティブな場合、コードはユーザーが既に非表示にしたことを「認識」しており、前のページに戻るつもりです。 (まあ、少なくともそれは彼らが得ようとしている振る舞いです...そして彼らはアニメーションを二度見ません)!

3
Stonetip