关于Silverlight  Navigation导航我一直想写一篇文章总结一下在项目中实际应用. Navigation导航是关联一个应用程序中实现功能多样化最基本需求. 导航也可以详细分为应用程序导航[应用中多为Page之间],外部导航, 集成浏览器导航等. Silverlight 发展今天版本4 当然也在这个方面做出很多努力. 从1.1 2.0 NavigationService到今天出现Frame控件,导航框架等. 逐渐丰富加强这方面运用. 本篇的目的自定义一个导航帮助类 实现Silverlight 中页面间导航操作. 先看看效果[稍微有点大]:

在项目中使用 新建三个测试页面 分别命名为:NvgTestPageOne /Two/Three.xaml ,默认初始页TestPageone.xaml, 可以从TestPageone跳转Two 跳转后可以通过Back按钮返回上一页. 当然各个页面间也支持直接跳转, 整个流程如图:

实现步骤: 自定义导航帮助类-NavigationHelper

A:引用空间

 
   
  1. using System.Collections;  
  2. using System.Collections.Generic;  
  3. using System.Reflection;  

B:在NavigationHelper声明变量:

 
   
  1. //声明  
  2. private static Grid FrameGrid = new Grid();//用存储导航页面和实现操作  
  3. private static Dictionary<string, string> getFrameDic = new Dictionary<string, string>();//记录整个跳转流程 

C:从当前页面跳转到一个新页面:

 
   
  1. /// <summary>  
  2.          /// 跳转新页面  
  3.          /// </summary>  
  4.          public static void NavigationFrame(UserControl sendpage)  
  5.          {  
  6.              App getcurentapp = Application.Current as App;  
  7.              if (getcurentapp != null)  
  8.              {  
  9.                //保存老页面  
  10.                  Grid rootgrid=getcurentapp.RootVisual as Grid;  
  11.                  UserControl getoldpageCon = rootgrid.Children[0] as UserControl;  
  12.                //测试发现问题:SendPage.Name有可能为空. 换利用Type的属性值   
  13.                  //添加时注意键不能重复  
  14.                  bool isreply = false;  
  15.                  foreach (KeyValuePair<string, string> getkey in NavigationHelper.NavigationHelp.getFrameDic)  
  16.                  {  
  17.                      if (getkey.Key.Equals(sendpage.GetType().Name + "old"))  
  18.                      {  
  19.                          isreply = true;//已经存在  
  20.                      }  
  21.                  }  
  22.    
  23.                  if (!isreply)  
  24.                  {  
  25.                      NavigationHelp.getFrameDic.Add(sendpage.GetType().Name + "old", getoldpageCon.GetType().Name);  
  26.                  }  
  27.    
  28.                  //跳转新页面  
  29.                  rootgrid.Children.Clear();  
  30.                  rootgrid.Children.Insert(0, sendpage);  
  31.                  getcurentapp.RootVisual = rootgrid;  
  32.              }  
  33.          } 

这个方法参数就是要跳转到页面UserControl. 通过操作App.RootVisual中Grid. 把新页面作为子控件添加到Grid.Children集合中. 当然跳转后如果Back返回操作. 我们必须记录这个跳转流程在Dictionary<stringstring>中. 页面间记录识别模式如下:

D:返回到上一页

 
   
  1. /// <summary>  
  2.          /// 自动跳转到上一页 类似IE的历史记录  
  3.          /// </summary>  
  4.          public static void NavigationBackFrame(UserControl CurrentPage)  
  5.          {  
  6.              bool isexit = false;//是否存在上一页 或是判断是否是根目录  
  7.              string backpage = string.Empty;  
  8.              foreach (KeyValuePair<string,string> getkey in NavigationHelp.getFrameDic)  
  9.              {  
  10.                  if (getkey.Key.Equals(CurrentPage.GetType().Name+"old"))  
  11.                  {  
  12.                      isexit = true;//存在  
  13.                      backpage =getkey.Value;  
  14.                      //MessageBox.Show(backpage); 测试成功  
  15.                  }  
  16.              }  
  17.    
  18.              if (!string.IsNullOrEmpty(backpage))  
  19.              {  
  20.                  //返回上一页  
  21.                  UserControl getbackControl = NavigationHelp.NavigationGetControlByName(backpage);  
  22.                  if (getbackControl != null)  
  23.                  {  
  24.                      App getcurentapp = Application.Current as App;  
  25.                      Grid rootgrid = getcurentapp.RootVisual as Grid;  
  26.    
  27.                      //跳转  
  28.                      rootgrid.Children.Clear();  
  29.                      rootgrid.Children.Insert(0, getbackControl);  
  30.                      getcurentapp.RootVisual = rootgrid;  
  31.                  }  
  32.              }  
  33.              else 
  34.              {  
  35.                  //不存在或是已经是根目录  
  36.                  MessageBox.Show("当前已经是根目录!");  
  37.              }  
  38.          } 

BackFram如上方法参数是当前页Control 传入后在Dictionary中查找对应跳转流程上一页记录. 然后跳转. 其中获取对应各页Control利用Assembly发射原理.具体方法实现如下:

F:获得一个具体页面Control:

 
   
  1. /// <summary>  
  2.          /// 通过Control的名称利用反射获取 UserContol实例对象./  
  3.          /// </summary>  
  4.          public static UserControl NavigationGetControlByName(string controlname)  
  5.          {  
  6.              //获取当前Assembly  
  7.              UserControl getpageControl = null;  
  8.              Assembly getcurrentass = Assembly.GetExecutingAssembly();  
  9.    
  10.              foreach (Type gettype in getcurrentass.GetTypes())  
  11.              {  
  12.                  if (gettype.Name.Equals(controlname))  
  13.                  {  
  14.                      //存在该Control  
  15.                      getpageControl = Activator.CreateInstance(gettype) as UserControl;      
  16.                  }  
  17.              }  
  18.              return getpageControl;  
  19.          } 

G:调用方式

如从Testpageone跳转到TestpageTwo页面 如下:

 
   
  1. //调用导航帮助类下公开当行方法 跳转到TestpagetTwo  
  2. UserControl sendpageCon=NavigationHelper.NavigationHelp.NavigationGetControlByName("NvgTestPageTwo");  
  3. NavigationHelper.NavigationHelp.NavigationFrame(sendpageCon);  

如果从TestPageTwo页面返回到TestpageOne 调用如下:

 
   
  1.  //调用导航帮助类 返回记录上一页  
  2. UserControl currentControl = NavigationHelper.NavigationHelp.NavigationGetControlByName("NvgTestPageTwo");  
  3. NavigationHelper.NavigationHelp.NavigationBackFrame(currentControl);  

直接跳转就更简单 同方式一类似.

如上一个简单方式实现Silverlight页面间跳转自定义帮助类. 简便快捷.当然如上只是简单跳转.实际运用中涉及到页面间参数的传递,值状态保留等问题. 完全可以在这个基础之上加以扩展即可.关于更多的Silverlight Navigation实现方式 稍后会有介绍.

关于Silverlight Navigation项目源代码下载见附件。