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