關于Silverlight Navigation導航我一直想寫一篇文章總結一下在項目中實際應用. Navigation導航是關聯一個應用程式中實作功能多樣化最基本需求. 導航也可以詳細分為應用程式導航[應用中多為Page之間],外部導航, 內建浏覽器導航等. Silverlight 發展今天版本4 當然也在這個方面做出很多努力. 從1.1 2.0 NavigationService到今天出現Frame控件,導航架構等. 逐漸豐富加強這方面運用. 本篇的目的自定義一個導航幫助類 實作Silverlight 中頁面間導航操作. 先看看效果[稍微有點大]:
<a href="http://blog.51cto.com/attachment/201201/164733652.jpg" target="_blank"></a>
在項目中使用 建立三個測試頁面 分别命名為:NvgTestPageOne /Two/Three.xaml ,預設初始頁TestPageone.xaml, 可以從TestPageone跳轉Two 跳轉後可以通過Back按鈕傳回上一頁. 當然各個頁面間也支援直接跳轉, 整個流程如圖:
<a href="http://blog.51cto.com/attachment/201201/164741554.png" target="_blank"></a>
實作步驟: 自定義導航幫助類-NavigationHelper
A:引用空間
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
B:在NavigationHelper聲明變量:
//聲明
private static Grid FrameGrid = new Grid();//用存儲導航頁面和實作操作
private static Dictionary<string, string> getFrameDic = new Dictionary<string, string>();//記錄整個跳轉流程
C:從目前頁面跳轉到一個新頁面:
/// <summary>
/// 跳轉新頁面
/// </summary>
public static void NavigationFrame(UserControl sendpage)
{
App getcurentapp = Application.Current as App;
if (getcurentapp != null)
{
//儲存老頁面
Grid rootgrid=getcurentapp.RootVisual as Grid;
UserControl getoldpageCon = rootgrid.Children[0] as UserControl;
//測試發現問題:SendPage.Name有可能為空. 換利用Type的屬性值
//添加時注意鍵不能重複
bool isreply = false;
foreach (KeyValuePair<string, string> getkey in NavigationHelper.NavigationHelp.getFrameDic)
{
if (getkey.Key.Equals(sendpage.GetType().Name + "old"))
{
isreply = true;//已經存在
}
}
if (!isreply)
NavigationHelp.getFrameDic.Add(sendpage.GetType().Name + "old", getoldpageCon.GetType().Name);
//跳轉新頁面
rootgrid.Children.Clear();
rootgrid.Children.Insert(0, sendpage);
getcurentapp.RootVisual = rootgrid;
}
}
這個方法參數就是要跳轉到頁面UserControl. 通過操作App.RootVisual中Grid. 把新頁面作為子控件添加到Grid.Children集合中. 當然跳轉後如果Back傳回操作. 我們必須記錄這個跳轉流程在Dictionary<string, string>中. 頁面間記錄識别模式如下:
<a href="http://blog.51cto.com/attachment/201201/164747125.png" target="_blank"></a>
D:傳回到上一頁
/// 自動跳轉到上一頁 類似IE的曆史記錄
public static void NavigationBackFrame(UserControl CurrentPage)
bool isexit = false;//是否存在上一頁 或是判斷是否是根目錄
string backpage = string.Empty;
foreach (KeyValuePair<string,string> getkey in NavigationHelp.getFrameDic)
if (getkey.Key.Equals(CurrentPage.GetType().Name+"old"))
isexit = true;//存在
backpage =getkey.Value;
//MessageBox.Show(backpage); 測試成功
if (!string.IsNullOrEmpty(backpage))
//傳回上一頁
UserControl getbackControl = NavigationHelp.NavigationGetControlByName(backpage);
if (getbackControl != null)
App getcurentapp = Application.Current as App;
Grid rootgrid = getcurentapp.RootVisual as Grid;
//跳轉
rootgrid.Children.Clear();
rootgrid.Children.Insert(0, getbackControl);
getcurentapp.RootVisual = rootgrid;
else
//不存在或是已經是根目錄
MessageBox.Show("目前已經是根目錄!");
BackFram如上方法參數是目前頁Control 傳入後在Dictionary中查找對應跳轉流程上一頁記錄. 然後跳轉. 其中擷取對應各頁Control利用Assembly發射原理.具體方法實作如下:
F:獲得一個具體頁面Control:
/// 通過Control的名稱利用反射擷取 UserContol執行個體對象./
public static UserControl NavigationGetControlByName(string controlname)
//擷取目前Assembly
UserControl getpageControl = null;
Assembly getcurrentass = Assembly.GetExecutingAssembly();
foreach (Type gettype in getcurrentass.GetTypes())
if (gettype.Name.Equals(controlname))
//存在該Control
getpageControl = Activator.CreateInstance(gettype) as UserControl;
return getpageControl;
G:調用方式
如從Testpageone跳轉到TestpageTwo頁面 如下:
//調用導航幫助類下公開當行方法 跳轉到TestpagetTwo
UserControl sendpageCon=NavigationHelper.NavigationHelp.NavigationGetControlByName("NvgTestPageTwo");
NavigationHelper.NavigationHelp.NavigationFrame(sendpageCon);
如果從TestPageTwo頁面傳回到TestpageOne 調用如下:
//調用導航幫助類 傳回記錄上一頁
UserControl currentControl = NavigationHelper.NavigationHelp.NavigationGetControlByName("NvgTestPageTwo");
NavigationHelper.NavigationHelp.NavigationBackFrame(currentControl);
直接跳轉就更簡單 同方式一類似.
如上一個簡單方式實作Silverlight頁面間跳轉自定義幫助類. 簡便快捷.當然如上隻是簡單跳轉.實際運用中涉及到頁面間參數的傳遞,值狀态保留等問題. 完全可以在這個基礎之上加以擴充即可.關于更多的Silverlight Navigation實作方式 稍後會有介紹.
關于Silverlight Navigation項目源代碼下載下傳見附件。
<a href="http://down.51cto.com/data/2359685" target="_blank">附件:http://down.51cto.com/data/2359685</a>
本文轉自chenkaiunion 51CTO部落格,原文連結:http://blog.51cto.com/chenkai/764872