2014-10-16 101 views
2

我在Windows Phone 8.1项目中使用Prism MVVM库进行WinRT。是否可以通过手机的后退按钮阻止后退导航,并处理ViewModel中的后退按钮?为Windows Phone 8.1运行时覆盖Prism中的后退按钮

具体情况:

  • 用户可以从项目的列表中选择一个项目(以下简称“有效的”项目) - 例如游戏中的玩家。该项目是该应用程序其余功能的参考,例如数据库查询。
  • 选择一个项目会将用户返回到上一个(主)页面。
  • 在同一个列表中,用户还可以删除不再需要的项目。应该可以删除所有项目。

问题:如果用户删除活动项目或最后一个项目,然后点击后退按钮,我最终会得到一个无效的活动项目。

为了防止这种情况,我想取消后退按钮导航并提示用户选择或创建另一个活动项目,理想情况下是从ViewModel。


更新:我现在已经添加了一个事件处理程序App.xaml.cs基于我下面怎么理解内特的评论。这应该重写它的应用范围:

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; 
    } 
} 

和订阅在构造函数中的事件:

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

这似乎是处理后退按钮按得很好,但它不会停止对现有导航。所以它在任何情况下都会返回,在默认情况下会返回两次。

+1

你不得不取消回府在应用程序本身的平台上使用HardwareButtons.BackPressed导航。然后,您可以随心所欲地使用任何逻辑,无论是应用程序范围的逻辑还是页面特定的逻辑。确保在事件参数中将'Handled'设置为'true'。 – 2014-10-16 18:44:38

+0

@NateDiamond谢谢你的帮助。我是否理解这意味着在应用程序级别上抛出由Prism提供的整个导航服务?这似乎很激进。它是否也会将使用来自ViewModel的信息的导航逻辑移动到View中?没有一种方法可以覆盖Prism框架内特定页面的后退导航吗? – jerry 2014-10-17 08:15:26

+0

对于想知道同样问题的任何人:当然有一种解决方法,在返回的页面的OnNavigatedTo()中处理此问题,将用户弹回到选择页面。虽然看起来不干净。 – jerry 2014-10-17 08:48:23

回答

3

这是可能的。这里是解决方案(主要由this discussion启发):

创建一个接口,使视图模型禁用后退导航:

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

在视图模型实现的接口:

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 
} 

在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 
相关问题