2014-10-16 74 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 
相關問題