简体   繁体   English

覆盖Prism for Windows Phone 8.1运行时中的“后退”按钮

[英]Overriding the Back Button in Prism for Windows Phone 8.1 Runtime

I'm using the Prism MVVM library for WinRT in a Windows Phone 8.1 project. 我在Windows Phone 8.1项目中将Prism MVVM库用于WinRT。 Is it possible to prevent back navigation via the phone's back button and handle the back button press in the ViewModel? 是否可以通过手机的后退按钮防止后退导航并在ViewModel中处理后退按钮的按下操作?

Concrete scenario: 具体方案:

  • The user can select one item (the "active" item) from a list of items - like a player in a game. 用户可以从项目列表中选择一个项目(“活动”项目),例如游戏中的玩家。 That item is a reference for the rest of the app's functionality, eg database queries. 该项目是应用程序其余功能(例如数据库查询)的参考。
  • Selecting one item returns the user to the previous (main) page. 选择一项将使用户返回到上一页(主页)。
  • In the same list, the user can also delete an item that is no longer needed. 在同一列表中,用户还可以删除不再需要的项目。 It should be possible to delete all items. 应该可以删除所有项目。

Problem: If the user deletes the active item or the last item and then taps the back button, I end up having an invalid active item. 问题:如果用户删除活动项目或最后一个项目,然后点击“后退”按钮,那么我最终将拥有无效的活动项目。

To prevent that, I'd like to cancel the back button navigation and prompt the user to select or create another active item, ideally from the ViewModel. 为避免这种情况,我想取消后退按钮导航,并提示用户选择或创建另一个活动项,最好是从ViewModel中选择。


Update: I have now added an event handler to the App.xaml.cs based on how I understood Nate's comment below. 更新:现在,根据我对Nate的评论的理解,我现在向App.xaml.cs添加了一个事件处理程序。 This should override it application-wide: 这应该覆盖整个应用程序:

private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
    Frame currentFrame = Window.Current.Content as Frame;
    if (currentFrame == null)
    {
        return;
    }
    if (currentFrame.Content is SelectionPage)
    {
        e.Handled = true;
    }
    else if (currentFrame.CanGoBack)
    {
        currentFrame.GoBack();
        e.Handled = true;
    }
}

and subscribing to the event in the constructor: 并在构造函数中订阅该事件:

#if WINDOWS_PHONE_APP
        HardwareButtons.BackPressed += HardwareButtons_BackPressed;
#endif

This seems to be handling the back button press just fine but it does not stop the existing navigation. 这似乎可以很好地处理后退按钮的按下,但不会停止现有的导航。 So it goes back in any case and twice in the default case. 因此无论如何它都会返回,默认情况下会返回两次。

This is possible. 这个有可能。 Here is the solution (mostly inspired by this discussion ): 这是解决方案(主要受此讨论启发):

Create an interface that allows view models to disable the back navigation: 创建一个允许视图模型禁用向后导航的接口:

public interface IRevertState
{
    bool CanRevertState();
    void RevertState();
}

In the view model implement the interface: 在视图模型中实现接口:

public class myViewModel : ViewModel, IRevertState {
public bool CanRevertState() {
    return (...) //condition under which back navigation should be disabled
}
public void RevertState() {
    (...) // optionally reset condition if required
}

In App.Xaml.cs handle the back navigation: 在App.Xaml.cs中处理向后导航:

#if WINDOWS_PHONE_APP
    protected override void OnHardwareButtonsBackPressed(object sender, BackPressedEventArgs e) {
        var page = (Page)((Frame)Window.Current.Content).Content;
        if (page.DataContext is IRevertState) {
            var revertable = (IRevertState)page.DataContext;
            if (revertable.CanRevertState()) {
                revertable.RevertState();
                e.Handled = true;
                return;
            }
        }
        base.OnHardwareButtonsBackPressed(sender, e);
    }
#endif

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM