如何处理Windows Phone 7上的后退按钮

43
在Windows Phone 7模拟器上,当按下硬件返回按钮时,默认行为是关闭当前应用程序。我想覆盖此默认行为,使其导航到我的应用程序中的上一页。经过一些研究,似乎可以通过重写OnBackKeyPress方法来实现,如下所示:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
    // do some stuff ...

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

然而,点击返回按钮仍然会关闭我的应用程序。在上述方法上设置断点发现它从未被调用。我在我的应用程序退出代码上设置了另一个断点,并且这个断点确实被触发。

是否还需要做其他事情来拦截返回按钮?


2
从我的MainPage.xaml中重写OnBackKeyPress()并调用e.Cancel对我来说效果很好。 - BrokeMyLegBiking
你可以处理返回按钮,查看我的这篇回答 - Santhu
3个回答

29

似乎不可能重写 OnBackKeyPress 方法来拦截后退键,除非您使用 Navigate 方法在应用程序的页面之间移动。

我之前的导航方法是更改根视觉元素,例如:

App.Current.RootVisual = new MyPage(); 

这意味着我可以将所有页面保留在内存中,因此我不需要缓存存储在它们上面的数据(其中一些数据是通过网络收集的)。

现在似乎我需要实际使用页面框架上的Navigate方法,它会创建一个新的实例,用于导航到我要导航的页面。

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

一旦我开始使用这种方法导航,我就可以按照我的问题中描述的方式覆盖后退按钮处理...


如果您使用导航,然后覆盖返回按钮,那么您可以为其实现新的行为(我自己检查过!)。 - RoguePlanetoid
有没有其他方法可以做到这一点?如果所有交互都在一个页面上进行,那怎么办?那么覆盖返回按钮就不可能了吗? - Hosam Aly
我建议在应用程序启动时设置一个“虚拟”页面,当应用程序开始时导航到您的主页面,这样您就可以覆盖主页面中的返回按钮。 - Pking

23

如果您不想使用默认的返回键行为,请在OnBackKeyPress中的CancelEventArgs参数中设置Cancel = true。在我的页面中,我已经重写了返回按钮,让它关闭一个Web浏览器控件而不是导航回去。

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

3

我能用这种技术实现我想要的功能,那就是在窗口中滑入滑出的控件隐藏时防止后退导航。默认情况下,该控件的可见性是折叠的。使用故事板控制何时变为可见或折叠。在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(它是一个网格)的Storyboard中,KeyTime设置为“00:00:01”,因为我希望它在滑动和淡出视图时保持可见。
注意2:if语句中包含StoryboardHideControlSlider.GetCurrentState() != ClockState.Active的原因是,如果用户两次点击返回按钮而Storyboard尚未完成,则会再次运行。这可以防止后退按钮取消导航回上一页。换句话说,如果Storyboard处于活动状态,则代码“知道”用户已经开始隐藏它并打算导航回上一页。(好吧,至少他们将得到这种行为...并且他们不会看到动画两次)!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接