WP8.1学习系列(第二十二章)——在页面之间导航
- 先決條件
- 創建導航應用
- Frame 和 Page 類
- 頁面模板中的導航支持
- 在頁面之間傳遞信息
- 緩存頁面
- 摘要
- 后續步驟
- 相關主題
- Page
- Frame
- NavigationCacheMode
本主題將討論基本的導航概念,并演示如何創建一個在兩個頁面之間進行導航的應用。
有關為你的應用選擇最佳導航模式的幫助,請參閱導航模式。
在操作時請參閱平面導航和分層導航模式,它們是應用功能大全系列的一部分。
?
路線圖:?本主題與其他主題有何關聯?請參閱:
- 使用 C# 或 Visual Basic 的 Windows 運行時應用的路線圖
- 使用 C++ 的 Windows 運行時應用的路線圖
?
你可以為你的應用創建多個頁面,并支持用戶在應用中的頁面之間進行導航,類似于在一個網站的網頁之間進行導航。Microsoft Visual Studio 包含頁面模板,這些模板可為使用 C# 或 Microsoft Visual Basic 的 Windows 運行時應用提供基本的導航支持。 在本主題中,我們使用頁面模板創建一個支持導航的簡單應用。
注意??
當我們討論 Windows 運行時應用的導航時,我們是指在一個應用的頁面之間進行導航,而不是在多個應用之間進行導航。
先決條件
本主題假定你可以使用 C# 或 Visual Basic 創建基本的 Windows 運行時應用。有關創建你的第一個 Windows 運行時應用的說明,請參閱使用 C# 或 Visual Basic 創建你的第一個 Windows 運行時應用。
創建導航應用
創建空白應用
此刻,解決方案已創建并且項目文件顯示在“解決方案資源管理器”中。有關項目文件的詳細信息,請參閱適用于 Windows 運行時應用的 C#、VB 以及 C++ 項目模板。
要點??首次運行 Visual Studio 時,它會提示你獲取開發人員許可證。有關詳細信息,請參閱獲取開發人員許可證。
隨即將顯示一個空白頁面。
接下來,在項目中添加兩個頁面。 我們將在這兩個頁面之間進行導航。 執行以下步驟兩次以添加兩個頁面。
添加基本頁面
當你執行完上述步驟兩次之后,如下文件應被添加到項目中。
- BasicPage1.xaml
- BasicPage1.xaml.cs 或 BasicPage1.xaml.vb
- BasicPage2.xaml
- BasicPage2.xaml.cs 或 BasicPage2.xaml.vb
現在,我們需要使用剛才在應用中添加的頁面。 對 BasicPage1.xaml 執行如下更改。
-
找到名為?pageTitle?的?TextBlock?元素,并將?Text?屬性更改為?Page 1。XAML 應如下所示("..." 代表未更改的其他屬性):
XAML <TextBlock x:Name="pageTitle" Text="Page 1" .../> -
將下列 XAML 作為第二個子元素添加到根?Grid。?StackPanel?元素應當為包含“后退”按鈕和頁面標題的?Grid的同級。
XAML <StackPanel Grid.Row="1"Margin="120,0,120,60"><HyperlinkButton Content="Click to go to page 2" Click="HyperlinkButton_Click"/> </StackPanel>?
對 BasicPage2.xaml 執行如下更改。
-
找到名為?pageTitle?的?TextBlock?元素,并將?Text?屬性更改為?Page 2。XAML 應如下所示:
XAML <TextBlock x:Name="pageTitle" Grid.Column="1" Text="Page 2" Style="{StaticResource PageHeaderTextStyle}"/> -
將下列 XAML 作為第二個子元素添加到根?Grid。?StackPanel?元素應當為包含“后退”按鈕和頁面標題的?Grid的同級。
XAML <StackPanel Grid.Row="1"Margin="120,0,120,60"><TextBlock HorizontalAlignment="Left" Name="tb1" Text="Hello World!"/> </StackPanel>
將如下代碼添加到 BasicPage1.xaml.cs 或 BasicPage1.xaml.vb 中的?BasicPage1?類。
C#private void HyperlinkButton_Click(object sender, RoutedEventArgs e) {this.Frame.Navigate(typeof(BasicPage2)); }
現在,新頁面已經準備好,我們需要使?BasicPage1?成為在應用啟動時最先顯示的頁面。 打開 app.xaml.cs/vb 并將?OnLaunched?方法更改為使用?BasicPage1?而不是?BlankPage?來調用?Frame.Navigate。 相關代碼行如下:
C# if(!rootFrame.Navigate(typeof(BasicPage1), e.Arguments)){ ... }注意??如果導航至應用的初始窗口框架失敗,則此處的代碼會使用?Navigate?的返回值引發應用異常。當Navigate?返回?true,導航即會發生。
現在你可以測試該應用。 啟動應用,并單擊顯示文字“單擊以轉到第 2 頁”的鏈接。 將顯示第二頁,且該頁面頂部應顯示“第 2 頁”。 在 Windows 應用商店應用中,請注意該頁面標題的左側有一個“后退”按鈕。 單擊該按鈕可返回第一頁。在 Windows Phone 應用商店應用中,單擊手機的“后退”按鈕以返回第一頁。
Frame 和 Page 類
在將更多功能添加到應用中之前,讓我們來看看我們所添加的頁面如何為應用提供導航支持。
文件 App.xaml.cs/vb/cpp 會創建?Frame(如果之前不存在),且會將?Frame?作為當前窗口的內容。 如果框架內容為空,則應用會導航到代碼隱藏 App.xaml 中指定的主頁。例如,在網格應用中,代碼為rootFrame.Navigate(typeof(GroupedItemsPage), "AllGroups") )。
Frame?類主要負責導航和實現方法,例如?Navigate、GoBack?和?GoForward。 使用?Navigate?方法在?Frame中顯示內容。 在前一個示例中,App.OnLaunched?方法將會創建一個 Frame,并將?BasicPage1?傳遞給Navigate?方法。 然后,該方法將應用的當前窗口的內容設置為?Frame。其結果是,應用的窗口包含一個包含BasicPage1?的?Frame。
BasicPage1?是?Page?類的子類。?Page?類具有?Frame?屬性,它是一種用于獲得包含?Page?的?Frame?的只讀屬性。 當?HyperlinkButton?的?Click?事件處理程序調用?Frame.Navigate(typeof(BasicPage2))?時,應用窗口中的Frame?將會顯示?BasicPage2?的內容。
?
?
?
掛起管理器
要點??
以下項目模板中提供了 SuspensionManager 幫助程序類:
| 中心應用、網格應用、拆分應用 |
| 中心應用、透視應用 |
| 中心應用 |
?
SuspensionManager 幫助程序類不與空白應用模板一起提供。
在設置過程中,SuspensionManager?會注冊?Frame。?SuspensionManager?是模板中 Common 文件夾中提供的幫助程序類,并且它提供的實現可用于在應用終止時存儲和加載狀態。
所有應用都會按照操作系統的指示在應用程序生命周期中移動。 不論何時應用由于某些原因(如資源限制、關閉、重啟等等)被系統終止,你作為開發人員必須在應用繼續時立即還原數據。 提供?SuspensionManager?有助于你執行此任務。
SuspensionManager?會捕獲全局會話狀態以簡化應用程序的進程生命周期管理。 會話狀態會在多種情形下自動清除,且應僅用于存儲便于在會話之間攜帶的信息,而在應用程序崩潰或進行升級時應丟棄該信息。 此信息基本上會包含過渡 UI 數據。
SuspensionManager?存在兩種屬性:SessionState 和 KnownTypes。
- SessionState?提供當前會話的全局會話狀態的訪問權限。 此狀態由 SaveAsync 方法序列化且由 RestoreAsync 方法還原。 所有數據使用 DataContractSerialization 保存和還原且應盡可能地壓縮。 強烈建議字符串為其他自包含數據類型。
- KnownTypes?存儲了為 DataContractSerializer 提供的自定義類型列表,在處于讀寫會話狀態時,SaveAsync 和 RestoreAsync 方法會使用該 DataContractSerializer。 可能會添加最初為空的其他類型以自定義序列化過程。
SuspensionManager?在 SessionState 字典中存儲狀態。 字典會針對唯一綁定到?Frame?的密鑰存儲 FrameState。 每個 FrameState 字典在該特定框架的導航狀態下保留每頁的狀態。 每個頁面會存儲導航參數以及用戶決定添加的任何其他狀態。
以下為其工作原理:當創建?Frame?后,如果你希望為該框架存儲狀態,則應立即注冊它。 使用以下調用(SuspensionManager.RegisterFrame(rootFrame, "AppFrame"))?進行注冊。 每個框架都應有與其關聯的唯一密鑰。 通常大部分應用僅有一個框架。 如果你聲明其他框架,則還需要注冊該框架。 當注冊某個框架后,會在該框架上設置兩個附加屬性。 第一個屬性是與框架關聯的密鑰,而第二個屬性是與框架關聯的會話狀態字典。 以前注冊的框架會立即還原其導航和狀態。 也可以取消注冊框架,則所有導航狀態和歷史記錄都會被丟棄。
現在我們來看看重要的調用:SaveAsync?和?RestoreAsync。?SaveAsync?用于保存整個 SessionState。 已通過 SuspensionManager.RegisterFrame 注冊的所有框架還將保留其當前導航堆棧,該堆棧依次為其活動頁面提供保存其數據的機會。 然后,根據 ApplicationData 的定義,使用 DataContractSerializer 對 SessionState 進行序列化并將其寫入本地文件夾中存儲的文件。
RestoreAsync 用于讀取以前保存的 SessionState。 已使用 RegisterFrame 注冊的所有框架還將還原其以前的導航狀態,該狀態為其活動頁面提供還原其狀態的機會。 當再次在?SaveAsync?中時,DataContractSerializer 用于取消序列化應用程序的本地文件夾的文件中存儲的狀態。
當用戶嘗試存儲其應用狀態時,通常會遇到兩種常見錯誤。
- 單個頁面存儲的類型必須可以使用 C# 和 VB 由 DataContractSerializer 序列化。 為此,必須注冊任何自定義類型,然后才能保存或還原該類型。?SuspensionManager?提供了 KnownTypes 集合,該集合將集合中的類型傳遞到 DataContractSerializer。 當調用?SuspensionManager?以還原 App.xaml 的代碼隱藏的?OnLaunched?覆蓋中的狀態時,最好在應用構造函數中注冊類型。 C# public App(){this.InitializeComponent();this.Suspending += OnSuspending;SuspensionManager.KnownTypes.Add(typeof(MyCustomType));}
- 使用導航傳遞的參數必須可以由平臺序列化。 當我們保存和還原導航堆棧時,會調用Frame.GetNavigationState()?和?Frame.SetNavigationState()。 這兩個調用都使用內部序列化格式且在Frame.Navigate()?中作為參數傳遞的所有類型必須可以由平臺序列化。
SuspensionManager?的使用在?NavigationHelper?的實施中被隱藏。
NavigationHelper?是頁面的實現方式,該頁面提供了以下重要便利:
- 面向的?Navigate?GoBack?和?GoForward?的事件處理程序。
- 導航的鼠標和鍵盤快捷方式。
- 導航狀態管理和進程生命周期管理。
除了提供所述的實現之外,還需要從在每個頁面上實現的?OnNavigatedTo()?和?OnNavigatedFrom()?事件處理程序中調用?NavigationHelper。 當發生這些事件時,NavigationHelper?將調用特定于頁面的 LoadState() 和 SaveState() 實現。 你可以在每個頁面上自定義這些函數的實現。應使用它們分別替換?OnNavigatedTo()?和OnNavigatedFrom()。
注意??在 Windows Phone 上,當應用暫停時調用?OnNavigatedFrom()。當應用恢復時,不調用?OnNavigatedTo()。
當頁面即將在?Frame?中顯示時會調用?OnNavigatedFrom()。 當我們導航至新頁面時,會加載與該頁面關聯的狀態。 如果正在還原頁面,則會還原之前為該頁面保存的狀態。 然后會調用 LoadState,這樣每個頁面才會響應。 LoadState 有兩個參數,最初的導航參數傳遞至 OnNavigatedTo 和之前頁面狀態(如果存在)。
當頁面不再顯示在?Frame?時會調用?OnNavigatedFrom()。 當我們導航離開頁面時,允許頁面保存其當前狀態。 將空字典傳遞至 SaveState()。 每個頁面都可以覆蓋 SaveState 并存儲鍵控字典中的對象(字符串至對象)。 然后,此字典與頁面關聯并添加到 SessionState,SuspensionManager?為給定的框架跟蹤該 SessionState。
?
注意??
- 單個頁面中存儲的任何數據都必須可供 DataContractSerializer 進行序列化。
- 僅存儲此處的過渡 UI 信息也很重要,因為如果應用由于終止之外的任何原因被關閉,則此狀態將丟失。
頁面模板中的導航支持
在創建導航頁面時,我們使用了“基本頁”模板。 該模板和支持導航的其他模板,可創建一個頁面,且在頁面的左上角提供一個“后退”按鈕。 該按鈕的樣式已設置為僅在它被啟用時才會顯示。 這就是你在第一頁上看不到“后退”按鈕,而在第二頁上看見它的原因。
以下頁面模板提供相同的導航支持。
- 基本頁
- 組詳細信息頁
- 分組項頁
- 項詳細信息頁
- 項頁
- 拆分頁
- 中心頁
- 搜索結果頁面
在頁面之間傳遞信息
我們的應用可在兩個頁面之間進行導航,但它真的沒有做什么有趣的事。 當一個應用包含多個頁面時,這些頁面經常需要共享信息。 讓我們將一些信息從第一頁傳遞到第二頁。
在 BasicPage1.xaml 中,用 XAML 替換你之前添加的?StackPanel。
XAML <StackPanel Grid.Row="1"Margin="120,0,120,60"><TextBlock Text="Enter your name"/><TextBox Width="200" HorizontalAlignment="Left" Name="tb1"/><HyperlinkButton Content="Click to go to page 2" Click="HyperlinkButton_Click"/> </StackPanel>在 BasicPage1.xaml.cs 或 BasicPage1.xaml.vb 中,使用以下代碼替換?HyperlinkButton_Click?事件處理程序。
C# private void HyperlinkButton_Click(object sender, RoutedEventArgs e) {this.Frame.Navigate(typeof(BasicPage2), tb1.Text); }在 BasicPage2.xaml.cs 或 BasicPage2.xaml.vb 中,使用以下代碼填寫空的?navigationHelper_LoadState?方法:
C# private void navigationHelper_LoadState(object sender, LoadStateEventArgs e) {string name = e.NavigationParameter as string;if (!string.IsNullOrWhiteSpace(name)){tb1.Text = "Hello, " + name;}else{tb1.Text = "Name is required. Go back and enter a name.";} }運行應用,在文本框中輸入你的名字,然后單擊顯示文字“單擊以轉到第 2 頁”的鏈接。 當你在?HyperlinkButton的?Click?事件中調用?this.Frame.Navigate(typeof(BasicPage2), tb1.Text);?時,tb1.Text?屬性將在?BasicPage2加載時被傳遞。 然后,BlankPage2?的?navigationHelper_LoadState?方法從事件數據獲得值,并用它顯示一條消息。
緩存頁面
當你運行上一個示例時,你可能已經注意到,如果你在?BasicPage2?上單擊“后退”按鈕,當?BasicPage1?上的TextBox?出現時,它是空的。 讓我們假設,應用的用戶想要返回到上一頁進行更改。 如果?BasicPage1?有許多字段要填寫,當應用返回到該頁時,用戶一定不會愿意看見重置的字段。 你可以使用?NavigationCacheMode?屬性來指定對一個頁面進行緩存。 在?BasicPage1?的構造函數中,將?NavigationCacheMode?設置為?Enabled。
C# public BasicPage1() {this.InitializeComponent();...this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled; }現在,當你運行應用并從?BasicPage2?導航回?BasicPage1?時,BasicPage1?上的?TextBox?將保留其值。
摘要
在本主題中,你學習了如何創建一個在頁面之間進行導航的簡單應用。 你學習了如何將信息從一個頁面傳遞到另一個頁面,以及如何指定對一個頁面的狀態進行緩存。
后續步驟
對于使用許多?Page?和?Frame?功能的完整示例,請參閱?XAML 導航示例。該示例包含此處未討論的功能,包括:
- 檢查導航堆棧(BackStack、ForwardStack)
- 檢查?CanGoBack?或?CanGoForward?并將它們作為隱藏和顯示導航 UI 的觸發器來使用
- 有關緩存頁面、GetNavigationState?和?CacheSize?的詳細信息
- 取消緩存和?Navigating?事件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
轉載于:https://www.cnblogs.com/bvin/p/4282633.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的WP8.1学习系列(第二十二章)——在页面之间导航的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows server 2008
- 下一篇: dell c6220II lsi阵列卡